簡體   English   中英

根據R中的名義價值計算實際美元價值

[英]Calculating real dollar values based on nominal values in R

我有一個包含一些變量的數據集

Plan <- c("A","A","A","B","B","B","B")    
Plan_Period <- c(1,2,3,1,2,3,4)
Plan_Elapsed_time <- c(0.5,1,0.25,1,0.5,0.3,0.25)
year <- c(2016,2017,2018,2015,2016,2017,2018)
Inflation <- c(1.014,1.012,1.012,1.013,1.012, 1.080,1.020)
Cost <- c(10,20,30,40,40,50,60)

data <- data.frame(Plan, Plan_Period, Plan_Elapsed_time, year, Inflation, Cost)

計划A的美元價值從名義金額轉換為實際金額的公式如下:

  • 期間1的實際值: 10*(1.014^0.5)*(1.012^1)*(1.012^0.25)

  • 期間2的實際值: 20*(1.012^1)*(1.012^0.25)

  • 期間3的實際價值: 30*(1.012^0.25)

我想使用其他函數在具有1000多個不同計划的數據集上執行此操作,而不是編寫for循環。

我感謝您的幫助!

使用Base R:我們也可以使用tidyverse

data=data.frame(Plan,Plan_Period ,Plan_Elapsed_time,year, Inflation,Cost

transform(data,m=Cost*ave(Inflation^Plan_Elapsed_time,Plan,
                 FUN=function(x)rev(cumprod(rev((x))))))
  Plan Plan_Period Plan_Elapsed_time year Inflation Cost        m
1    A           1              0.50 2016     1.014   10 10.22103
2    A           2              1.00 2017     1.012   20 20.30045
3    A           3              0.25 2018     1.012   30 30.08960
4    B           1              1.00 2015     1.013   40 41.92150
5    B           2              0.50 2016     1.012   40 41.38352
6    B           3              0.30 2017     1.080   50 51.42179
7    B           4              0.25 2018     1.020   60 60.29778

 library(tidyverse)
 data%>%
   group_by(Plan)%>%
   mutate(m=Cost*rev(cumprod(rev(Inflation^Plan_Elapsed_time))))
# A tibble: 7 x 7
# Groups:   Plan [2]
  Plan  Plan_Period Plan_Elapsed_time  year Inflation  Cost     m
  <fct>       <dbl>             <dbl> <dbl>     <dbl> <dbl> <dbl>
1 A            1.00             0.500  2016      1.01  10.0  10.2
2 A            2.00             1.00   2017      1.01  20.0  20.3
3 A            3.00             0.250  2018      1.01  30.0  30.1
4 B            1.00             1.00   2015      1.01  40.0  41.9
5 B            2.00             0.500  2016      1.01  40.0  41.4
6 B            3.00             0.300  2017      1.08  50.0  51.4
7 B            4.00             0.250  2018      1.02  60.0  60.3

library(data.table)
setDT(data)[,m:=(Cost*rev(cumprod(rev(Inflation^Plan_Elapsed_time)))),by=Plan][]
   Plan Plan_Period Plan_Elapsed_time year Inflation Cost        m
1:    A           1              0.50 2016     1.014   10 10.22103
2:    A           2              1.00 2017     1.012   20 20.30045
3:    A           3              0.25 2018     1.012   30 30.08960
4:    B           1              1.00 2015     1.013   40 41.92150
5:    B           2              0.50 2016     1.012   40 41.38352
6:    B           3              0.30 2017     1.080   50 51.42179
7:    B           4              0.25 2018     1.020   60 60.29778

不需要循環。 使用data.table包,您可以按組計算累積的通貨膨脹,然后將結果乘以成本:

data <- data.frame(
  Plan = c("A","A","A","B","B","B","B"),    
  Plan_Period=c(1,2,3,1,2,3,4),
  Plan_Elapsed_time=c(0.5,1,0.25,1,0.5,0.3,0.25),
  year=c(2016,2017,2018,2015,2016,2017,2018),
  Inflation= c(1.014,1.012,1.012,1.013,1.012, 1.080,1.020),
  Cost= c(10,20,30,40,40,50,60)
)

library(data.table)
setDT(data)
data <- data[order(Plan, -Plan_Period)][, Cum_Inflation := cumprod(Inflation^Plan_Elapsed_time), by = Plan][, Real_Cost := Cost * Cum_Inflation]
print(data)
#>    Plan Plan_Period Plan_Elapsed_time year Inflation Cost Cum_Inflation Real_Cost
#> 1:    A           3              0.25 2018     1.012   30      1.002987  30.08960
#> 2:    A           2              1.00 2017     1.012   20      1.015022  20.30045
#> 3:    A           1              0.50 2016     1.014   10      1.022103  10.22103
#> 4:    B           4              0.25 2018     1.020   60      1.004963  60.29778
#> 5:    B           3              0.30 2017     1.080   50      1.028436  51.42179
#> 6:    B           2              0.50 2016     1.012   40      1.034588  41.38352
#> 7:    B           1              1.00 2015     1.013   40      1.048038  41.92150

基於@Sathish的評論的優化版本:

data <- data.frame(
  Plan = c("A","A","A","B","B","B","B"),    
  Plan_Period=c(1,2,3,1,2,3,4),
  Plan_Elapsed_time=c(0.5,1,0.25,1,0.5,0.3,0.25),
  year=c(2016,2017,2018,2015,2016,2017,2018),
  Inflation= c(1.014,1.012,1.012,1.013,1.012, 1.080,1.020),
  Cost= c(10,20,30,40,40,50,60)
)

library(data.table)
setDT(data)[order(Plan, -Plan_Period), real_val := Cost * cumprod( Inflation ^ Plan_Elapsed_time ), by = .(Plan)]
data
#>    Plan Plan_Period Plan_Elapsed_time year Inflation Cost real_val
#> 1:    A           1              0.50 2016     1.014   10 10.22103
#> 2:    A           2              1.00 2017     1.012   20 20.30045
#> 3:    A           3              0.25 2018     1.012   30 30.08960
#> 4:    B           1              1.00 2015     1.013   40 41.92150
#> 5:    B           2              0.50 2016     1.012   40 41.38352
#> 6:    B           3              0.30 2017     1.080   50 51.42179
#> 7:    B           4              0.25 2018     1.020   60 60.29778

這是一個tidyverse解決方案。 我認為我理解了所解釋的邏輯,即較大的計划周期是較新的,因此要乘以的inflation ^ plan_elapsed1較少。 在這里,我們arrange獲取按plan ,然后按plan_period排序的行,然后使用cumprod制定正確的條件以乘以cost

library(tidyverse)
data <- tibble(
  Plan = c("A","A","A","B","B","B","B"),
  Plan_Period = c(1,2,3,1,2,3,4),
  Plan_Elapsed_time = c(0.5,1,0.25,1,0.5,0.3,0.25),
  year = c(2016,2017,2018,2015,2016,2017,2018),
  Inflation = c(1.014,1.012,1.012,1.013,1.012, 1.080,1.020),
  Cost = c(10,20,30,40,40,50,60)
)

data %>%
  `colnames<-`(str_to_lower(colnames(.))) %>%
  mutate(deflate = inflation ^ plan_elapsed_time) %>%
  group_by(plan) %>%
  arrange(plan, desc(plan_period)) %>%
  mutate(
    cum_deflate = cumprod(deflate),
    real_cost = cost * cum_deflate
    ) %>%
  select(plan:cost, real_cost)
#> # A tibble: 7 x 7
#> # Groups:   plan [2]
#>   plan  plan_period plan_elapsed_time  year inflation  cost real_cost
#>   <chr>       <dbl>             <dbl> <dbl>     <dbl> <dbl>     <dbl>
#> 1 A              3.             0.250 2018.      1.01   30.      30.1
#> 2 A              2.             1.00  2017.      1.01   20.      20.3
#> 3 A              1.             0.500 2016.      1.01   10.      10.2
#> 4 B              4.             0.250 2018.      1.02   60.      60.3
#> 5 B              3.             0.300 2017.      1.08   50.      51.4
#> 6 B              2.             0.500 2016.      1.01   40.      41.4
#> 7 B              1.             1.00  2015.      1.01   40.      41.9

reprex軟件包 (v0.2.0)於2018-04-09創建。

考慮by與內sapply呼吁運行條件的產品:

by_list <- by(data, data$Plan, function(sub){      
  sub$RealValue <- sapply(sub$Plan_Period, function(i) 
    sub$Cost[sub$Plan_Period == i] * prod((sub$Inflation[sub$Plan_Period >= i])^(sub$Plan_Elapsed_time[sub$Plan_Period >= i]))
  )      
  return(sub)
})

finaldata <- do.call(rbind, unname(by_list))

finaldata
#   Plan Plan_Period Plan_Elapsed_time year Inflation Cost RealValue
# 1    A           1              0.50 2016     1.014   10  10.22103
# 2    A           2              1.00 2017     1.012   20  20.30045
# 3    A           3              0.25 2018     1.012   30  30.08960
# 4    B           1              1.00 2015     1.013   40  41.92150
# 5    B           2              0.50 2016     1.012   40  41.38352
# 6    B           3              0.30 2017     1.080   50  51.42179
# 7    B           4              0.25 2018     1.020   60  60.29778

不知道我是否誤解了這個問題,但是為該數據編寫一個for循環似乎相當簡單。

n<-length(Plan)

for(i in 1:n){
 if (Plan[i]=="A" & Plan_Period[i]==1){
print(10*(1.014^0.5)*(1.012^1)*(0.25^1.012))
}
else if (Plan[i]=="A" & Plan_Period[i]==2){
print(20*(1.012^1)*(0.25^1.012))
}
 else if (Plan[i]=="A" &  Plan_Period[i]==3){
print(30*(1.012^0.25))
} 

else {
print(0)
  }
 }

希望這會有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM