如何像在 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)))

另请注意此答案下方的评论以了解另一种变体。