沿着数据行的集合。在R中具有NA的帧

时间:2014-05-09 07:59:33

标签: r cumsum

假设的情况是data.frame

中存在NA
> 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)是一个不错的选择,您可以提供替代方法。

2 个答案:

答案 0 :(得分:3)

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

data[ is.na(data) ] <- 0
data.frame(t(apply(data,1,cumsum)))

答案 1 :(得分:3)

西蒙绝对是最简单的。我很惊讶地从这个练习中学到了一些东西: 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))