我想在我的数据帧上执行一些操作,但是我在性能方面遇到了一些问题,所以我想知道如何加快代码的性能。 我的数据有几列,如果列X为0,我想对其他列进行一些操作(添加和最大)。如果X为1,则不执行任何操作(X只能为1或0)
df <- data.frame(X = c(0,0,1,0,1),Y = c(10,0,0,3,7),Z = c(2,2,0,4,5))
df
X Y Z
1 0 10 2
2 0 0 2
3 1 0 0
4 0 3 4
5 1 7 5
现在我的代码看起来像:
for(i in 1:(nrow(df)-1)){
if(df$X[i] == 0){
df$Y[i+1] <- df$Y[i]+df$Y[i+1]
df$Z[i+1] <- max(df$Z[i],df$Z[i+1])
}
}
结果如下:
df
X Y Z
1 0 10 2
2 0 10 2
3 1 10 2
4 0 3 4
5 1 10 5
有没有办法更有效地写这个? 另外,很多行只包含0,所以我想知道是否有一种有效的方法可以跳过这些行的操作,因为值不会改变。
编辑: 由于我对规则有点不明确,所以在这里它们更详细: Y应该总结直到再次有1(总和(包括行的值,其中1是)应该用1替换行的值。同样的原则应该应用于X变量,但这次使用max()函数。
非常感谢!
答案 0 :(得分:1)
这样的事情怎么样?这将再现您的预期输出:
df <- data.frame(X = c(0,0,1,0,1),Y = c(10,0,0,3,7),Z = c(2,2,0,4,5))
df %>%
mutate(
group = cumsum(c(0, diff(X) == -1))) %>%
group_by(group) %>%
mutate(
n = 1:n(),
Y = cumsum(Y),
Z = ifelse(n > 1, max(Z, lead(Z, default = 0)), Z)) %>%
ungroup() %>%
select(X, Y, Z)
# # A tibble: 5 x 3
# X Y Z
# <dbl> <dbl> <dbl>
#1 0. 10. 2.
#2 0. 10. 2.
#3 1. 10. 2.
#4 0. 3. 4.
#5 1. 10. 5.
说明:基于0
的群组条目 - 由1
终止的系列;将Y
替换为cumsum
的{{1}};将Y
替换为该行中的最大条目,并从第二行(Z
)开始替换下一行。