【问题标题】:How to collapse NA and merge multiple columns into one column如何折叠 NA 并将多列合并为一列
【发布时间】:2015-03-29 03:18:52
【问题描述】:

我有一个合并的数据集,如下所示:

    V3    V1.x               V2.x   V1.y                 V2.y   V982 V2163 
1  10075  Whitten Jamie L.   1225    <NA>                NA     2     2   
2  10421  Yates Sidney R.    1252    Yates Sidney R.     1252   2     0      
3  10520  Gonzalez Henry B.   445    Gonzalez Henry B.   445    0     0       
4  10573  Brown George E.Jr.  134    Brown George E.Jr.  134    0     0    
5  29584  <NA>                NA     Cubin  Barbara      254    0     0

我通过匹配 V3 合并了两个数据集。如您所见,两个数据集都有 V1 和 V2 变量,这两个变量并不相同。

我有两个问题。

1) 有什么方法可以在不生成 V1.x V1.y 的情况下合并两个数据集?我的意思是我想知道是否有任何方法可以让 V1 看起来像这样

V1
Whitten Jamie L.
Yates Sidney R.
Gonzalez Henry B.
Brown George E.Jr.
Cubin  Barbara

我使用了简单的合并命令,例如merge(df1, df2, by=c("V3")

2) 如果没有 V1.x 和 V1.y 就无法合并这两个数据集,那么如何折叠 NA 并合并这两列?

我在论坛中搜索了其他问题,找到了类似的命令 cbind(data[1], mycol = na.omit(unlist(data[-1]))) na.omit(stack(df))df2&lt;-apply(df,1,function(x) x[!is.na(x)])。但它们都不能很好地工作。当我没有 V982 V3 或 V2163 等不相关的列时,这些命令似乎有效。我不知道如何通过将 NA 与维护其他列(如 V982 V2163 等)合并来合并这两列。

感谢您的帮助!

【问题讨论】:

  • 您的最终数据集是否应该只有V3V982V2163?或者应该是V3V1.xV1.yV982V2163,然后是V2.xV2.y的组合,这样来自一个的NAs与NA一起归档另一个?
  • 也许你想要merge(df1, df2, by=c("V3","V1")
  • @MaratTalipov,这行不通(首先,因为您缺少),)因为那样您将失去那些在V1&lt;NA&gt; 上拥有NA&lt;NA&gt; 的人V2(如果您要将 V2 添加到您的 by 语句中。
  • @AndrewTaylor,说得好。
  • 那么df$V1 &lt;- with(df,ifelse(is.na(V1.x),V1.y,V1.x))呢?

标签: r merge collapse


【解决方案1】:

1) 有什么方法可以在不生成 V1.x 的情况下合并两个数据集 V1.y?

您可以尝试此解决方案,它将作用于df1df2 中存在的所有列:

d1 <- df1[df1$V3 %in% df2$V3,]
d2 <- df2[df2$V3 %in% df1$V3,]

m <- match(d2$V3,d1$V3)
z <- sapply(names(d1),function(s) ifelse(is.na(d1[,s]),d2[m,s],d1[,s]))
result <- cbind(z,d2[m,setdiff(names(d2),names(d1)),drop=F])

它从df1df2 中选择V1 列中具有共同值的行,然后使用第二个数据集中的对应值填充第一个数据集中的NA 用于其他列。

2) 如果我不能在没有 V1.x 和 V1.y 的情况下合并这两个数据集,那么 如何折叠 NA 并合并这两列?

如果你已经合并了你的数据,你可以试试这个解决方案(它只适用于V1列):

df$V1 <- with(df,ifelse(is.na(V1.x),V1.y,V1.x))

【讨论】:

  • 我认为你的第一种方法删除了最后一行(我也可能错了,因为没有提供数据集)
  • 是的,我想在真实的数据集上进行测试。
【解决方案2】:

如果我正确理解您的最终产品,使用 dplyr 会很简单:

df1 %>%
    select(V3, V982) %>%
    left_join(select(df2,V3,V2163), by=V3)

给出:

     V3 V982 V2163
1 10075    2     2
2 10421    2     0
3 10520    0     0
4 10573    0     0
5 29584    0     0

【讨论】:

  • 我认为他也想合并 V1/V2 列。看起来它只是 V3 上的一个内部连接
  • 我的内部连接(通过dplyr::inner_join)看起来就像 OP 的输出。我是否遗漏了一个会使 V1 和 V2 崩溃的论点?
【解决方案3】:

在这里,我正在回答您提供合并数据集的第二个问题。

这个想法是创建一个模式('pat')来指定需要折叠的列的“前缀”。使用grep 获取这些列的数字索引(“indx”)。从原始数据集(“df”)中删除列并创建一个新数据集“df1”。使用lapply循环“pat”,使用grep子集相似的前缀列,使用pmaxna.rm=TRUE获取折叠列,最后将列表元素分配给新列(“V1,V2”)在“df1”中。

pat <- paste0('^V', 1:2, '..$')
indx <- grep(paste(pat, collapse='|'), names(df))
df1 <- df[-indx]
df1[paste0('V',1:2)] <- lapply(pat, function(x) do.call(pmax,
                           c(df[grep(x, names(df))], na.rm=TRUE)))
df1
#     V3 V982 V2163                 V1   V2
#1 10075    2     2   Whitten Jamie L. 1225
#2 10421    2     0    Yates Sidney R. 1252
#3 10520    0     0  Gonzalez Henry B.  445
#4 10573    0     0 Brown George E.Jr.  134
#5 29584    0     0     Cubin  Barbara  254

或者您可以使用max.col 查找非NA值的“行索引”并获取具有“行/列”索引的元素。

 df1[paste0('V', 1:2)] <- lapply(pat, function(x) {
            x1 <- df[grep(x, names(df))]
            x1[cbind(1:nrow(x1), max.col(!is.na(x1)))]})

数据

df <- structure(list(V3 = c(10075L, 10421L, 10520L, 10573L, 29584L), 
V1.x = c("Whitten Jamie L.", "Yates Sidney R.", "Gonzalez Henry B.", 
"Brown George E.Jr.", NA), V2.x = c(1225L, 1252L, 445L, 134L, 
NA), V1.y = c(NA, "Yates Sidney R.", "Gonzalez Henry B.", 
"Brown George E.Jr.", "Cubin  Barbara"), V2.y = c(NA, 1252L, 
445L, 134L, 254L), V982 = c(2L, 2L, 0L, 0L, 0L), V2163 = c(2L, 
0L, 0L, 0L, 0L)), .Names = c("V3", "V1.x", "V2.x", "V1.y", 
"V2.y", "V982", "V2163"), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5"))

【讨论】:

  • 所以这是采用已经完成的错误合并,并折叠 V1 和 V2?
  • 现在更清楚地阅读问题。是的,我采用了错误的合并数据 :-) 这似乎是一个有趣的问题,而不是通常的 merge 类型。所以,基本上,我是在回答第二个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
相关资源
最近更新 更多