【问题标题】:Merging different data frames depending on column value根据列值合并不同的数据框
【发布时间】:2018-07-31 21:00:55
【问题描述】:

我有一个数据框df1

df1<- data.frame(ID = c("A","B","A","A","B"),CLASS = c(1,1,2,1,4))
 ID CLASS
1  A     1
2  B     1
3  A     2
4  A     1
5  B     4

还有另外两个数据框A和B

   > A<- data.frame(CLASS = c(1,2,3), DESCRIPTION = c("Unknown", "Tall", "Short"))
  CLASS DESCRIPTION
1     1     Unknown
2     2        Tall
3     3       Short

> B <- data.frame(CLASS = c(1,2,3,4), DESCRIPTION = c("Big", "Small", "Medium", "Very Big"))
  CLASS DESCRIPTION
1     1         Big
2     2       Small
3     3      Medium
4     4    Very Big

我想根据df1 的 ID 和类合并这三个数据框,得到类似这样的结果:

      ID CLASS DESCRIPTION
1  A     1     Unknown
2  B     1         Big
3  A     2        Tall
4  A     1     Unknown
5  B     4    Very Big

我知道我可以将它合并为df1 &lt;- merge(df1, A, by = "CLASS"),但我找不到添加条件(可能“如果”太多)以根据 ID 也合并 B 的方法。 我需要一种有效的方法来执行此操作,因为我将其应用于超过 2M 行。

【问题讨论】:

  • 你能解释一下df1的第5行吗? CLASS = 4 是怎么结束的?
  • @coffeinjunky 抱歉,在 df1 中应该是 4。已编辑。

标签: r dataframe merge


【解决方案1】:

将ID变量添加到A和B,rbindA和B一起,并使用ID和CLASS到merge:

A$ID = 'A'
B$ID = 'B'

AB <- rbind(A, B)

merge(df1, AB, by = c('ID', 'CLASS'))

  ID CLASS DESCRIPTION
1  A     1     Unknown
2  A     1     Unknown
3  A     2        Tall
4  B     1         Big
5  B     4    Very Big

我建议在创建数据时使用stringsAsFactors = FALSE:

df1 <- data.frame(ID = c("A","B","A","A","B"),CLASS = c(1,1,2,1,4),
                  stringsAsFactors = FALSE)
A <- data.frame(CLASS = c(1,2,3), 
                DESCRIPTION = c("Unknown", "Tall", "Short"),
                stringsAsFactors = FALSE)
B <- data.frame(CLASS = c(1,2,3,4), 
                DESCRIPTION = c("Big", "Small", "Medium", "Very Big"),
                stringsAsFactors = FALSE)

【讨论】:

    【解决方案2】:

    要一次性合并多个数据帧,Reduce 通常会很有帮助:

    out <- Reduce(function(x,y) merge(x,y, by = "CLASS", all.x=T), list(df1, A, B))
    out
      CLASS ID DESCRIPTION.x DESCRIPTION.y
    1     1  A       Unknown           Big
    2     1  B       Unknown           Big
    3     1  A       Unknown           Big
    4     2  A          Tall         Small
    5     4  B          <NA>      Very Big
    

    如您所见,所有数据框中的列都添加了后缀(默认为merge 行为)。这允许您应用任何您想要获得最终列的逻辑。例如,

    out$Description <- ifelse(out$ID == "A", as.character(out$DESCRIPTION.x), as.character(out$DESCRIPTION.y))
    > out
      CLASS ID DESCRIPTION.x DESCRIPTION.y Description
    1     1  A       Unknown           Big     Unknown
    2     1  B       Unknown           Big         Big
    3     1  A       Unknown           Big     Unknown
    4     2  A          Tall         Small        Tall
    5     4  B          <NA>      Very Big    Very Big
    

    请注意,ifelse 是矢量化的并且非常高效。

    【讨论】:

      【解决方案3】:

      dplyr 解决方案:

      library(dplyr)
      bind_rows(lst(A,B),.id="ID") %>% inner_join(df1)
      #   ID CLASS DESCRIPTION
      # 1  A     1     Unknown
      # 2  A     1     Unknown
      # 3  A     2        Tall
      # 4  B     1         Big
      # 5  B     4    Very Big
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-04
        • 1970-01-01
        • 2023-01-08
        • 1970-01-01
        • 1970-01-01
        • 2015-07-14
        • 1970-01-01
        相关资源
        最近更新 更多