如何像在 Stata 中一样在 R 中使用滞后
How to use lag in R as in Stata
我试图在 R 中重新创建一个 Stata 代码片段,但我遇到了障碍。
在 Stata 中,滞后函数在应用时给出此结果:
A B
1 2
1 2
1 2
1 2
replace A=B if A==A[_n-1]
A B
1 2
2 2
1 2
2 2
如果我尝试在 R 中复制,我会得到以下信息:
temp <- data.frame("A" = rep(1,4), "B" = rep(2,4))
temp
A B
1 2
1 2
1 2
1 2
temp <- temp %>% mutate(A = ifelse(A==lag(A,1),B,A))
temp
A B
2 2
2 2
2 2
2 2
我需要它和 Stata 中的一样。
看起来我们需要在每个 运行
之后更新
for(i in 2:nrow(temp)) temp$A[i] <- if(temp$A[i] == temp$A[i-1])
temp$B[i] else temp$A[i]
temp
# A B
#1 1 2
#2 2 2
#3 1 2
#4 2 2
或者如评论中@G.Grothendieck所说,可以用
紧凑
for(i in 2:nrow(temp)) if (temp$A[i] == temp$A[i-1]) temp$A[i] <- temp$B[i]
这里有一个函数可以做到这一点:
lagger <- function(x,y){
current = x[1]
out = x
for(i in 2:length(x)){
if(x[i] == current){
out[i] = y[i]
}
current = out[i]
}
out
}
lagger(temp$A, temp$B)
[1] 1 2 1 2
lag
不会在这里使用,因为它使用 A
中的原始值,而在每次迭代中,问题需要最新更新的值。
定义一个 Update
函数并使用 purrr 包中的 accumulate2
应用它。它 returns 一个列表所以取消它。
library(purrr)
Update <- function(prev, A, B) if (A == prev) B else A
transform(temp, A = unlist(accumulate2(A, B[-1], Update)))
给予:
A B
1 1 2
2 2 2
3 1 2
4 2 2
另一种写法是在 gsubfn 中使用 fn$
,这会导致公式参数被解释为函数。它构建的函数按照遇到的顺序使用公式中的自由变量作为参数。
library(gsubfn)
library(purrr)
transform(temp, A = unlist(fn$accumulate2(A, B[-1], ~ if (prev == A) B else A)))
另请注意此答案下方的评论以了解另一种变体。
我试图在 R 中重新创建一个 Stata 代码片段,但我遇到了障碍。
在 Stata 中,滞后函数在应用时给出此结果:
A B
1 2
1 2
1 2
1 2
replace A=B if A==A[_n-1]
A B
1 2
2 2
1 2
2 2
如果我尝试在 R 中复制,我会得到以下信息:
temp <- data.frame("A" = rep(1,4), "B" = rep(2,4))
temp
A B
1 2
1 2
1 2
1 2
temp <- temp %>% mutate(A = ifelse(A==lag(A,1),B,A))
temp
A B
2 2
2 2
2 2
2 2
我需要它和 Stata 中的一样。
看起来我们需要在每个 运行
之后更新for(i in 2:nrow(temp)) temp$A[i] <- if(temp$A[i] == temp$A[i-1])
temp$B[i] else temp$A[i]
temp
# A B
#1 1 2
#2 2 2
#3 1 2
#4 2 2
或者如评论中@G.Grothendieck所说,可以用
紧凑for(i in 2:nrow(temp)) if (temp$A[i] == temp$A[i-1]) temp$A[i] <- temp$B[i]
这里有一个函数可以做到这一点:
lagger <- function(x,y){
current = x[1]
out = x
for(i in 2:length(x)){
if(x[i] == current){
out[i] = y[i]
}
current = out[i]
}
out
}
lagger(temp$A, temp$B)
[1] 1 2 1 2
lag
不会在这里使用,因为它使用 A
中的原始值,而在每次迭代中,问题需要最新更新的值。
定义一个 Update
函数并使用 purrr 包中的 accumulate2
应用它。它 returns 一个列表所以取消它。
library(purrr)
Update <- function(prev, A, B) if (A == prev) B else A
transform(temp, A = unlist(accumulate2(A, B[-1], Update)))
给予:
A B
1 1 2
2 2 2
3 1 2
4 2 2
另一种写法是在 gsubfn 中使用 fn$
,这会导致公式参数被解释为函数。它构建的函数按照遇到的顺序使用公式中的自由变量作为参数。
library(gsubfn)
library(purrr)
transform(temp, A = unlist(fn$accumulate2(A, B[-1], ~ if (prev == A) B else A)))
另请注意此答案下方的评论以了解另一种变体。