将Excel公式转换为使用上一行结果的{R}代码

时间:2016-11-22 09:52:28

标签: r excel dataframe data.table

我在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 shift函数:

  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

2 个答案:

答案 0 :(得分:2)

您可以使用shift中的data.table功能。

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

答案 1 :(得分:1)

使用dplyr,您可以通过滞后获得先前的值:

library(dplyr)

我重新创建了数据框:

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)))
                        )
               )

然而,事实证明scaled_time应该是输出,第一行将初始化为0(未计算)。因此,其中一个选项是循环。

编辑:For Loop Solution

虽然将循环作为最后一个选项,但对于小型数据帧,这是一个快速的解决方案:

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])))

}