R:通过一个公共ID合并列,任何行都没有任何NA? [关闭]

Posted

技术标签:

【中文标题】R:通过一个公共ID合并列,任何行都没有任何NA? [关闭]【英文标题】:R: merging columns by a common ID without any NA on any row? [closed] 【发布时间】:2011-10-24 06:02:35 【问题描述】:

给定具有缺失值的数据,插补是用一些值替换缺失值的过程。目标是忽略缺失值的行,用 NA 表示。这样的行可以被视为数据的一个组成部分,因此该过程称为item imputation

输入

df1 <- data.frame(ID=c(1,2,5,6),V1=c(7,77,777,NA))
df2 <- data.frame(ID=c(1,3,5,6),V2=c(6,66,666,6666))
df3 <- data.frame(ID=c(1,3,5,6),V3=c(9,NA,999,9999))

或者是 CSV 格式,缺失值用 NA 标记

data.csv      data2.csv        data3.csv

ID V1         ID V2            ID V3
1  7          1  6             1  9
2  77         2  NA            2  NA
3  NA         3  66            3  NA
4  NA         4  NA            4  NA
5  777        5  666           5  999
6  NA         6  6666          6  9999

输出

预期结果是

ID V1   V2   V3
1  7    6    9
5  777  666  999

我们只想要没有任何 NA 值的行。

如何将输入数据与列 V1、V2、V3 和行上没有 NA 的公共列 ID 合并?


使用 SQLDF 合并具有公共 ID 且无 NA 的列的示例解决方案

library(sqldf)
# Read in the data: with CSV, you can use read.csv or fread from data.table
df1 <- data.frame(ID=c(1,2,5,6),V1=c(7,77,777,NA))
df2 <- data.frame(ID=c(1,3,5,6),V2=c(6,66,666,6666))
df3 <- data.frame(ID=c(1,3,5,6),V3=c(9,NA,999,9999))
#
sqldf("SELECT a.ID, a.V1, b.V2, c.V3 FROM df1 a, df2 b, df3 c WHERE a.ID=b.ID AND b.ID=c.ID AND V1!='NA'")

导致

   ID   V1  V2  V3
1   1    7   6   9
2   5  777 666 999

【问题讨论】:

哇,这一定是我遇到过的最糟糕的问题之一。 ID = 1 怎么办?你想告诉我们什么?您的可重现代码在哪里? 我假设预期结果只是预期结果的一行? ID == 1 怎么了? 63 是否应该在预期结果中,但在缺少数据的地方有 NA?代码很棒,但不要指望我们仅凭它就能破译你 Q 的意图! @hhh:真的吗?由于 ID 1 像 ID 5 一样属于所有 3 个 data.frames,因此应该按照什么规则排除它? 是的,这样更好。请注意,您显示的数据不是 CSV,我们处理这些数据并不容易,因为它们不可重现或 R 代码/输出。 【参考方案1】:

这是一个仅限 R 的基本版本,它不关心有多少合并。假设数据框在列表 l 中 - 请参阅对 Q 的编辑以获取该格式的示例数据:

for(i in seq_along(l[-1])) 
    if(i == 1) 
        m <- merge(l[[i]], l[[i+1]])
     else 
        m <- merge(m, l[[i+1]])
    

m <- m[!apply(is.na(m), 1, any), ]

给出所需的输出

> m
  ID  V1  V2  V3
1  1   7   6   9
2  5 777 666 999

要读入数据,这样的事情应该可以工作

l <- lapply(list.files(pattern = glob2rx("data*.csv")), read.table, 
            header = TRUE)

或者如果它们真的是 CSV

l <- lapply(list.files(pattern = glob2rx("data*.csv")), read.csv)

那么就可以使用上面的代码来处理了。

【讨论】:

【参考方案2】:

出于对在这个问题中精美展示的俳句艺术形式的尊重,我将提供以下答案/疯狂猜测:

library(reshape)
dats <- lapply( dir(), read.csv )
mgd <- merge_recurse( dats, by="ID" )
na.sel <- apply( mgd, 1, function(x) any(is.na(x)) )
mgd <- mgd[!na.sel,]

请注意,这假设您实际上想要 ID==1。

感谢@Joris 提供merge_recurse 提示。

【讨论】:

tss tss tss...merge_recurse? :***.com/questions/6942662/… 哦,我喜欢!每天学习新东西。 @hhh 这解决了您的问题吗?我会检查自己,但如果没有可重复的例子,这是不可能的。我可以建议阅读***.com/questions/5963269/… 吗?有了你的代表,我很惊讶这是必要的。

以上是关于R:通过一个公共ID合并列,任何行都没有任何NA? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

R - 检查 r 数据框行的任何列中是不是存在 NA,如果存在,则删除该行 [重复]

根据R中的条件合并列

r通过ID [duplicate]重新排列行

如何在 R 中合并同一数据框中的行(基于特定列下的重复值)?

如何合并 dplyr R 中两个不同列的行数据?

基于公共列合并多个数据框[重复]