2

假设的情况是存在 NA 在data.frame

> a <- c(1:5, NA, 7:10)
> b <- 1:10
> c <- 1:10
> 
> data <- data.frame(a,b,c)
> data
    a  b  c
1   1  1  1
2   2  2  2
3   3  3  3
4   4  4  4
5   5  5  5
6  NA  6  6
7   7  7  7
8   8  8  8
9   9  9  9
10 10 10 10
> data <- data.frame(a,b,c)
> data.frame(t(apply(data,1,cumsum)))
    a  b  c
1   1  2  3
2   2  4  6
3   3  6  9
4   4  8 12
5   5 10 15
6  NA NA NA
7   7 14 21
8   8 16 24
9   9 18 27
10 10 20 30

我想要的结果是

    a  b  c
1   1  2  3
2   2  4  6
3   3  6  9
4   4  8 12
5   5 10 15
6   0  6 12
7   7 14 21
8   8 16 24
9   9 18 27
10 10 20 30

或者

    a  b  c
1   1  2  3
2   2  4  6
3   3  6  9
4   4  8 12
5   5 10 15
6   NA  6 12
7   7 14 21
8   8 16 24
9   9 18 27
10 10 20 30

我不确定apply(..., cumsum)是一个好的选择,您可以提供替代方法。

4

2 回答 2

4

西蒙的绝对是最简单的。我很惊讶地从这个练习中学到了一些东西:1.cumsum没有na.rm参数 2.sum(NA, na.rm=TRUE)等于 0

这是使我得到相同解决方案的代码:

cumsum.alt <- function(x){
    res <- NaN*seq(x)
    for(i in seq(x)){
        res[i] <- sum(x[1:i], na.rm=TRUE)
    }
    res
}

t(apply(data, 1, cumsum.alt))

要返回 NA,可以稍作修改:

cumsum.alt <- function(x){
    res <- NaN*seq(x)
    for(i in seq(x)){
        if(sum(is.na(x[1])) == i){
            res[i] <- NaN
        } else {
            res[i] <- sum(x[1:i], na.rm=TRUE)
        }
    }
    res
}

t(apply(data, 1, cumsum.alt))
于 2014-05-09T08:17:02.883 回答
3

鉴于您想要的结果(您不介意NA成为0),我想最简单的方法是首先删除NA使用的值is.na,然后像以前一样继续。

data[ is.na(data) ] <- 0
data.frame(t(apply(data,1,cumsum)))
于 2014-05-09T08:06:03.193 回答