R 压缩不同列中带有NA的行以创建一行

R 压缩不同列中带有NA的行以创建一行,r,dataframe,plyr,R,Dataframe,Plyr,我有一个这样的数据框 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)) 获取此data.frame id a b c d 1 A 1 2 3 4 2

我有一个这样的数据框

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))
获取此data.frame

      id  a  b  c  d
    1  A  1  2  3  4
    2  B 10 20 30 40
它可以工作,但是有没有更直接的方法不用使用
colSums
,对行进行某种压缩,为每个“id”创建一行,因为在每个“id”中,所有列只有一个值,其余的都是NAs。我在寻找其他东西的时候在某处遇到过类似的请求,但现在找不到了


谢谢

当我遇到类似问题时,这里推荐了一个解决方案,使用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
请注意,这将为您提供一个
数据.table
,而不是
数据.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

via:

当我遇到类似问题时,使用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
请注意,这将为您提供一个
数据.table
,而不是
数据.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

via:

我不知道这要容易得多,但是:

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

test我不知道这要简单得多,但是:

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
使用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
>test[is.na(test)]聚合(.~id,data=test,FUN=“sum”)
id a b c d
1A1234
2 B 10 20 30 40
使用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
>test[is.na(test)]聚合(.~id,data=test,FUN=“sum”)
id a b c d
1A1234
2 B 10 20 30 40

另一个
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])

另一种
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])

使用
base的解决方案

apply(test, 2, function(x) unique(na.omit(x)))

使用
base的解决方案

apply(test, 2, function(x) unique(na.omit(x)))

可能重复:另一种方法:
split(na.omit(unlist)(test[,-1],use.names=FALSE)),c(FALSE,TRUE))
可能重复:另一种方法:
split(na.omit(unlist)(test[,-1],use.names=FALSE)),c(FALSE,TRUE))
谢谢。这当然是同一个问题。我会记得“折叠记录”而不是“压缩行”注意:
x[!is.na(x)]
相当于
na.omit(x)
。谢谢。这当然是同一个问题。我会记得“折叠记录”而不是“压缩行”注意:
x[!is.na(x)]
相当于
na.omit(x)
。谢谢。我经常使用plyr和重塑,只是没有想到在这里尝试它们!:(是的,可能“id”不是一个安全的变量名。谢谢。我经常使用plyr和重塑,只是没有想到在这里试用它们!:(是的,可能“id”不是一个安全的变量名。@Jilber谢谢你的建议。由于我的data.frame太大,熔铸技术填满了我的RAM,然后交换,结果又重新启动了。在这种情况下,可能是base-R。我的声誉不允许我对它进行投票,但我愿意。Thxagain@Jilber谢谢你的邀请建议。由于我的data.frame太大,熔铸技术填满了我的RAM,然后交换,结果又重新启动。在这种情况下,可能是base-R。我的声誉不允许我对其进行升级,但我想再次升级。Thx