聚合数据帧并删除NA

时间:2013-06-19 18:33:32

标签: r dataframe

我有一个数据框,我想重塑它,以便每个观察obs只有一行。以下是示例数据:

data <- data.frame("obs" = c('1','1','1','2','2'),
                   "value1" = c(1,NA,NA,NA,NA),
                   "value2" = c(NA,NA,3,1,NA),
                   "value3" = c(NA,2,NA,NA,5))

数据如下所示:

  obs value1 value2 value3
   1      1     NA     NA
   1     NA     NA      2
   1     NA      3     NA
   2     NA      1     NA
   2     NA     NA      5

我希望将其重塑为:

obs  value1  value2  value3
1       1      3       2
2       NA     1       5

谢谢!

3 个答案:

答案 0 :(得分:4)

library(data.table)
dt = data.table(dat)

dt[, lapply(.SD, function(x) x[!is.na(x)]), by = obs]

如果给定观察的每个值有多个条目,这将使用R的回收逻辑来填补其余部分。

答案 1 :(得分:2)

我会这样做,使用 plyr

foo <- function(x){
    if (all(is.na(x))) return(NA)
    else return(x[!is.na(x)])
}

ddply(dat,.(obs),colwise(foo))

当然,这假设您确实在obs的每个值的每列中最多只有一个非NA值。

如果不是这种情况,并且您想要取多个值的平均值,您可以尝试按照Justin的建议:

mean(x[!is.na(x)])

答案 2 :(得分:2)

基础解决方案:

out <- lapply(split(data, data$obs), function(x) {
    ans <- lapply(x[, -1], na.omit)
    data.frame(obs = x[1, 1], t(sapply(ans, "[", 1)))
})

do.call(rbind, out)

## > do.call(rbind, out)
##   obs value1 value2 value3
## 1   1      1      3      2
## 2   2     NA      1      5