我正在尝试在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中的相同。
lag
在这里将不使用,因为它使用A
中的原始值,而在每次迭代中,问题都需要最近更新的值。定义Update
函数,然后使用purrr软件包中的accumulate2
应用它。它返回一个列表,因此将其取消列出。
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)))
也请注意此答案下方的评论,以供其他选择。
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
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]