2014-02-07 47 views
1

我有一个有多个列的数据框。对于一列,我想计算累计总和,但缺少值时会遇到一些问题。cumsum在NA之后重新开始

#sample data 
test <- c(-1.2, 4.6, -8.3, 5, 8, 1, -2, NA, NA, NA, -3, 5.1, 1.9) 
test <- as.data.frame(test) 

#This gives NA after NAs occurred 
sum_test <- lapply(test, FUN=cumsum) 

sum_test 
$test 
[1] -1.2 3.4 -4.9 0.1 8.1 9.1 7.1 NA NA NA NA NA NA 

#This continues with adding to pre-NA value after last NA 
sum_test <- lapply(test, function(x) ave(x, is.na(x), FUN=cumsum)) 

sum_test 
$test 
[1] -1.2 3.4 -4.9 0.1 8.1 9.1 7.1 NA NA NA 4.1 9.2 11.1 

不过,我想实现的是,在NAS cumsum重新开始后:

-1.2 3.4 -4.9 0.1 8.1 9.1 7.1 NA NA NA -3 2.1 4 

可以这样做?

回答

3

这应该做的伎俩:

test <- c(-1.2, 4.6, -8.3, 5, 8, 1, -2, NA, NA, NA, -3, 5.1, 1.9) 
tmp <- rle(is.na(test)) 
ind <- rep(seq_along(tmp$value), tmp$lengths) 
as.vector(unlist(tapply(test, ind, cumsum))) 
5

这里g定义分组变量,然后我们分别申请cumsum在每个组:

test <- c(-1.2, 4.6, -8.3, 5, 8, 1, -2, NA, NA, NA, -3, 5.1, 1.9) 
g <- cumsum(is.na(head(c(0, test), -1))) 
ave(test, g, FUN = cumsum) 

这给:

[1] -1.2 3.4 -4.9 0.1 8.1 9.1 7.1 NA NA NA -3.0 2.1 4.0 

添加:需要注意的是head(c(0, test), -1)只是滞后test所以dplyr的lag功能可以用来略微缩短这个:

library(dplyr) 
ave(test, cumsum(is.na(lag(test))), FUN = cumsum) 
+0

这是伟大的。可以用'na.omit'来解决同样的问题吗? –

+0

'na.omit'输出一个通常比其输入短的向量,所以在这里似乎不太有用。 –

相关问题