我有一个像这样的数据框
test <- data.frame(id = rep(LETTERS[1:2],each = 3),
a = c(1,NA,NA,10,NA,NA),
b = c(2,NA,NA,20,NA,NA),
c = c(NA,3,NA,NA,30,NA),
d = c(NA,NA,4,NA,NA,40))
我得到了这个数据帧,并希望将其转换为每个唯一的'id'只有一行,而数据帧中没有NA。
我这样做
ddply(test,
.variables = 'id',
.fun = function(df){
colSums(df[,1:4], na.rm = T)})
获取此data.frame
id a b c d
1 A 1 2 3 4
2 B 10 20 30 40
它有效,但是有一种更直接的方法可以不使用colSums
,有点压缩行为每个'id'创建一行,因为在每个'id'中,所有列都有只有一个值,其余是NA。我确实遇到了类似的请求,同时寻找其他东西,但现在找不到它!
由于
答案 0 :(得分:5)
使用R基本功能
> test[is.na(test)] <-0
> aggregate(.~id, data=test, FUN="sum")
id a b c d
1 A 1 2 3 4
2 B 10 20 30 40
答案 1 :(得分:1)
这是一个解决方案,当我遇到类似的问题时,建议我使用data.table和is.na:
require(data.table)
DT=data.table(test)
unique(DT[, lapply(.SD, function(x) x[!is.na(x)]), by = id])
id a b c d
1: A 1 2 3 4
2: B 10 20 30 40
请注意,这会为您提供data.table
,而不是data.frame
。如果您不熟悉这种数据结构,可以轻松转换它:
data.frame(unique(DT[, lapply(.SD, function(x) x[!is.na(x)]), by = id]))
id a b c d
1 A 1 2 3 4
2 B 10 20 30 40
答案 2 :(得分:1)
我不知道这更容易,但是:
test <- data.frame(id.l = rep(LETTERS[1:2],each = 3),
a = c(1,NA,NA,10,NA,NA),
b = c(2,NA,NA,20,NA,NA),
c = c(NA,3,NA,NA,30,NA),
d = c(NA,NA,4,NA,NA,40))
x <- melt(test, id.l = id, na.rm = T)
dcast(x, id.l ~ variable)
# id.l a b c d
# 1 A 1 2 3 4
# 2 B 10 20 30 40
我不得不更改您的ID列的名称,因为我无法生成id = id
。
答案 3 :(得分:1)
另一个dplyr
解决方案如下:
library(dplyr)
test %>% group_by(id) %>% summarise(a = na.omit(a)[1], b = na.omit(b)[1],
c = na.omit(c)[1], d = na.omit(d)[1])
答案 4 :(得分:0)
使用base
apply(test, 2, function(x) unique(na.omit(x)))