我试图弄清楚 dplyr 是否有一种方法可以逐行计算变量,以便它可以引用之前一条记录计算的结果。
这是使用 for 循环实现我想要的代码:
x <- data.frame(x1 = c(1:10))
#This works.
x$x2[1] <- 0
for (i in 2:nrow(x)) {
x$x2[i] <- x$x2[i-1]*1.1 + 1
}
我天真的 dplyr 尝试,不起作用:
#This doesn't work. "Error: object'x1' not found"
x %>% mutate(x2 = ifelse(x1 == 1, 0, lag(x2)*1.1 + 1))
如果能找到 dplyr 解决方案就好了,因为此步骤是严重依赖它的工作流程的一部分。
谢谢你。
编辑:
上面是我正在尝试做的事情的简化示例。封闭式解决方案将不起作用,因为所应用的函数比此处显示的更复杂和动态。例如,假设“add_var”和“pwr_var”是随机整数,我想计算这个:
x$x2[1] <- 0
for (i in 2:nrow(x)) {
x$x2[i] <- ( x$x2[i-1]*1.1 + x$add_var[i] ) ^ x$pwr_var[i]
}
一般来说,如果您想计算依赖于先前值的值,最好使用
Reduce
。这是您的数据的示例
x %>% mutate(x3 = Reduce(function(a,b) a*1.1+1, 1:(n()-1), 0, acc=T))
但在您的示例中,该术语有一个封闭形式,不依赖于迭代。你可以做的
x %>% mutate(x4=(1.1^(row_number()-1)-1)/(1.1-1)*1)
如果您确实想使用扩展符号,那么您可以使用库 magrittr,定义一个执行转换的函数,然后应用管道运算符。另外,对于 dplyr,请使用 data_frame 对象,而不是 data.frame 对象。
library(dplyr)
library(magrittr)
x <- data_frame(x1 = c(1:10))
f_x <- function(x){(x-1)*1.1+1}
x$x2 <-x %$% x1 %>% f_x
你的代码对我有用。这是结果:
x1 x2
1 1 0.000000
2 2 1.000000
3 3 2.100000
4 4 3.310000
5 5 4.641000
6 6 6.105100
7 7 7.715610
8 8 9.487171
9 9 11.435888
10 10 13.579477
您可以尝试使用 dplyr 代码行吗:
x %>% mutate(x2 = ifelse(x1 == 1, 0, lag(x2)*1.1 + 1))