我有一个数据框,我想重塑它,以便每个观察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
谢谢!
答案 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