【问题标题】:Can I replace NAs when joining two data frames with dplyr?使用 dplyr 连接两个数据帧时可以替换 NA 吗?
【发布时间】:2016-08-23 20:32:19
【问题描述】:

我想加入两个数据框。一些列名重叠,并且在数据框的重叠列之一中有NA 条目。这是一个简化的例子:

df1 <- data.frame(fruit = c('apples','oranges','bananas','grapes'), var1 = c(1,2,3,4), var2 = c(3,NA,6,NA), stringsAsFactors = FALSE)
df2 <- data.frame(fruit = c('oranges','grapes'), var2=c(5,6), var3=c(7,8), stringsAsFactors = FALSE)

我是否可以使用 dplyr 连接函数来连接这些数据框并自动优先处理非NA 条目,以便让“var2”列在连接的数据框中没有NA 条目?就像现在一样,如果我调用left_join,它会保留NA 条目,如果我调用full_join,它会复制行。

示例数据

> df1
    fruit var1 var2
1  apples    1    3
2 oranges    2   NA
3 bananas    3    6
4  grapes    4   NA
> df2
    fruit var2 var3
1 oranges    5    7
2  grapes    6    8

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    coalesce 可能是您需要的。它用对应位置的第二个向量的值填充第一个向量的 NA:

    library(dplyr)
    df1 %>% 
            left_join(df2, by = "fruit") %>% 
            mutate(var2 = coalesce(var2.x, var2.y)) %>% 
            select(-var2.x, -var2.y)
    
    #     fruit var1 var3 var2
    # 1  apples    1   NA    3
    # 2 oranges    2    7    5
    # 3 bananas    3   NA    6
    # 4  grapes    4    8    6
    

    或者使用data.table,它会进行就地替换:

    library(data.table)
    setDT(df1)[setDT(df2), on = "fruit", `:=` (var2 = i.var2, var3 = i.var3)]
    df1
    #      fruit var1 var2 var3
    # 1:  apples    1    3   NA
    # 2: oranges    2    5    7
    # 3: bananas    3    6   NA
    # 4:  grapes    4    6    8
    

    【讨论】:

    • 感谢您的回答!对于 dplyr 解决方案,如果有多个重叠列,是否有办法让 mutate 步骤从 x 和 y 合并所有具有相同名称的列?
    • 一种更通用的无需对列进行硬编码的方法可能是在合并后重塑数据。这是我可以提供的示例df1 %&gt;% left_join(df2, by = "fruit") %&gt;% reshape(varying = 3:4, dir = "long") %&gt;% group_by(fruit, var1, var3) %&gt;% summarise_each(funs(na.omit(.)), -id, -time)
    【解决方案2】:

    将 purrr 与 dplyr 一起使用可能是应用于多列的解决方案:

    library(purrr)
    library(dplyr)
    
    df<-left_join(df1,df2,by="fruit")
    map2_dfr(df[3],df[4],~ifelse(is.na(.x),.y,.x)) %>% 
    bind_cols(df[c(1,2,5)],.)
    
        fruit var1 var3 var2.x
    1  apples    1   NA      3
    2 oranges    2    7      5
    3 bananas    3   NA      6
    4  grapes    4    8      6
    

    【讨论】:

      猜你喜欢
      • 2015-03-25
      • 1970-01-01
      • 2018-12-11
      • 2017-01-30
      • 2021-12-06
      • 1970-01-01
      • 2020-10-26
      • 2018-05-01
      相关资源
      最近更新 更多