将Excel公式转换成使用前一行结果的R代码

我在Excel中有一个计算示例,我需要将它转换为更大的数据集的R代码。

我的数据应该是这样的:

time value cum_value floor scaled_time 0 0 0 0 0 1 1 1 1 1 2 0.975 1.975 1 1 3 0.95 2.925 3 2.038961039 4 0.925 3.85 4 3.098982099 5 0.9 4.75 5 4.185278042 6 0.875 5.625 6 5.302030016 7 0.85 6.475 7 6.453196107 

在Excel中使用此类公式计算“缩放时间”列(示例显示的是第6行):

 =scaled_time5+((floor6-floor5)/((cum_value6-floor5)/(time6-scaled_time5))) 

由于这是指以前的行中的单元格,我无法在R中编码。

这是我到目前为止(使用data.table shiftfunction:

  DF$Scaled_Time=shift(DF$Scaled_Time, 1L, "lag")+ ((DF$Floor-shift(DF$Floor,1L,"lag"))/ ((DF$Cum_Value-shift(DF$Floor,1L,"lag"))/ (DF$Time-shift(DF$Scaled_Time, 1L, "lag")))) 

这不起作用,并提出这个错误:

 Error in `$<-.data.frame`(`*tmp*`, "Scaled_Time", value = numeric(0)) : replacement has 0 rows, DF has 2246400 In addition: Warning messages: 1: In shift(DF$Floor, 1L, "lag") : NAs introduced by coercion 2: In shift(DF$Floor, 1L, "lag") : NAs introduced by coercion 

你可以使用data.tableshiftfunction。

 df$result = 2.038961 df[, result := shift(result)+((floor-shift(floor))/((cum_value-shift(floor))/(time-shift(result)))) ] 

使用dplyr你可以得到以前的价值滞后:

 library(dplyr) 

我重新创build了数据框:

 vv <- data.frame(time=c(3,4,5,6,7), value=c(0.95,0.925,0.9,0.875,0.85), cum_value=c(3.925,4.85,5.75,6.625,7.475), floor=c(3,4,5,6,7), scaled_time=c(2.038961039,3.098982099,4.185278042,5.302030016,6.453196107)) 

这是一个简单的计算,你可以使用你的:

时间+((楼层价值 – 上一楼层价格)/(cum_value-上一楼层价值))将写为:

 > vv %>% mutate(V4=time+((floor-lag(floor,1))/(cum_value-lag(floor,1)))) time value cum_value floor scaled_time V4 1 3 0.950 3.925 3 2.038961 NA 2 4 0.925 4.850 4 3.098982 4.540541 3 5 0.900 5.750 5 4.185278 5.571429 4 6 0.875 6.625 6 5.302030 6.615385 5 7 0.850 7.475 7 6.453196 7.677966 

如果我没有错过原始公式中的括号,应该是这样的:

 vv %>% mutate(V=lag(scaled_time,1)+ ((floor-lag(floor,1))/ ((cum_value-lag(floor,1))/(time-lag(scaled_time,1))) ) ) 

但是,事实certificate,scaled_time应该是输出,第一行将被初始化为0(不计算)。 所以其中一个选项是循环。

编辑:为循环解决scheme

虽然最后一个选项是循环,但在小数据框的情况下,这是一个快速解决scheme:

 vv$scaled_time <- 0 for (i in 2: nrow(vv)) { vv$scaled_time[i]= vv$scaled_time[i-1]+ ((vv$floor[i]-vv$floor[i-1])/((vv$cum_value[i]-vv$floor[i-1])/(vv$time[i]-vv$scaled_time[i-1]))) } 
Interesting Posts