【问题标题】:join matching columns in a data.frame or data.table连接 data.frame 或 data.table 中的匹配列
【发布时间】:2012-04-12 16:35:03
【问题描述】:

我有以下data.frames:

a <- data.frame(id = 1:3, v1 = c('a', NA, NA), v2 = c(NA, 'b', 'c'))
b <- data.frame(id = 1:3, v1 = c(NA, 'B', 'C'), v2 = c("A", NA, NA))
> a
  id   v1   v2
1  1    a <NA>
2  2 <NA>    b
3  3 <NA>    c
> b
  id   v1   v2
1  1 <NA>    A
2  2    B <NA>
3  3    C <NA>

注意:两个表中都没有定义 v1 或 v2 的 id;每个 id 值的每一列中只有一个唯一的非 NA 值

我想在“id”的匹配值上合并这些数据框:

ab <- merge(a, b, by = "id")

但我还想将v1v2 这两列合并,这样data.frame ab 将如下所示:

ab <- data.frame(id = 1:3, v1 = c("a", "B", "C"), v2 = c("A", "b", "c"))

> ab
  id v1 v2
1  1  a  A
2  2  B  b
3  3  C  c

相反,我明白了:

> merge(a, b, by = "id")
  id v1.x v2.x v1.y v2.y
1  1    a <NA> <NA>    A
2  2 <NA>    b    B <NA>
3  3 <NA>    c    C <NA>

同时使用data.framedata.table 的例子会很有帮助,所以这里是上面的data.table 版本:

A <- data.table(a, key = 'id')
B <- data.table(b, key = 'id')
A[B]

【问题讨论】:

    标签: r merge dataframe plyr data.table


    【解决方案1】:

    如果您的数据像上面所说的那么简单,joran 的答案可能是最简单的方法。以下是基地的可能方法:

    a <- data.frame(id = 1:3, v1 = c('a', NA, NA), v2 = c(NA, 'b', 'c'))
    b <- data.frame(id = 1:3, v1 = c(NA, 'B', 'C'), v2 = c("A", NA, NA))
    
    decider <- function(x, y) factor(ifelse(is.na(x), as.character(y), as.character(x)))
    data.frame(mapply(a, b, FUN = decider))
    

    如果您的数据有不同的 id(有些重叠,有些没有,那么这里有一种不同的方法:

    a <- data.frame(id = c(1,2,4,5), v1 = c('a', NA, "q", NA), v2 = c(NA, 'b', 'c', "e"))
    b <- data.frame(id = 1:4, v1 = c(NA, "A", "C", 'B'), v2 = c("A", NA, "D", NA))
    
    decider <- function(x, y) factor(ifelse(is.na(x), as.character(y), as.character(x)))
    
    DF <- data.frame(mapply(a, b, FUN = decider))
    DF2 <- rbind(b[!b$id %in% DF$id , ], DF)
    DF2 <- DF2[order(DF2$id), ]
    rownames(DF2) <- 1:nrow(DF2)
    

    【讨论】:

    • +1 啊,我明白你的意思了。一些 id 出现在一个 df 中,但没有出现在另一个 df 中。我怀疑我的一般策略在这种情况下仍然有效,假设 OP 的规范仍然成立,这意味着孤立的 id 中不会有任何 NA 值。
    【解决方案2】:

    您指定的合并类型可能无法使用merge(带有数据框),尽管说这通常会导致被证明是错误的。

    您还省略了一些细节:对于每个id 值,每列中是否总是有一个唯一的非NA 值?如果是这样,这将起作用:

    ab <- rbind(a,b)
    > colFun <- function(x){x[which(!is.na(x))]}
    > ddply(ab,.(id),function(x){colwise(colFun)(x)})
      id v1 v2
    1  1  a  A
    2  2  B  b
    3  3  C  c
    

    类似的策略也应该适用于data.tables:

    abDT <- data.table(ab,key = "id")
    > abDT[,list(colFun(v1),colFun(v2)),by = id]
         id V1 V2
    [1,]  1  a  A
    [2,]  2  B  b
    [3,]  3  C  c
    

    【讨论】:

    • 答案是“是”,总会有“一个唯一的非NA值”;这是更清晰的方式来说明我试图在第一个代码块下的注释中传达的内容:“两个表中都没有定义 v1 或 v2 的 id”
    • +1 表示 colwise。我不知道这个功能,但它看起来很漂亮。
    • @TylerRinker 我不确定我明白你所说的不同 id 的意思。
    • 另外,@MatthewDowle 肯定能够建议一种更巧妙的方法来将colFun 应用于每一列,而无需明确列出它们。
    • 嗨。一个成语是DT[,lapply(.SD,colFun),by=id]
    猜你喜欢
    • 2021-10-23
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2021-09-12
    • 2021-05-10
    • 2014-01-30
    • 2015-12-25
    • 1970-01-01
    相关资源
    最近更新 更多