我在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
答案 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])))
}