【问题标题】:merge dataframes and report conflicts in r在 r 中合并数据框并报告冲突
【发布时间】:2020-03-03 10:58:59
【问题描述】:

我有两个数据框,df1 和 df2,它们需要以这样一种方式连接(合并),即一个 df 中的 NA 被第二个 df 中的值替换,该值基于一些关键列以及发现冲突的地方,它在生成的 df 中报告。例如,

> df1 <- data.frame(c1=c("a","b","c"),c2=c(1,2,3),c3=c("m",NA,"k"),c4=c(1,2,NA),c5=c("z1","z2","z3"))  
> df2 <- data.frame(c1=c("d","b","c"),c2=c(1,2,3),c3=c("m","j","p"),c4=c(1,NA,8),c5=c("k1","k2","k3"))

> df1
---
c1 c2 c3 c4 c5
a  1  m  1  z1
b  2  NA 2  z2
c  3  k  NA z3

> df2
----
c1 c2 c3 c4 c5
d  1  m  1 k1
b  2  j NA k2
c  3  p  8 k3

我可以使用 rqdatatable 库中的 natural_join 函数来合并两个数据帧,以便一个 df 中的 NA 被另一个 df 中的值替换。但是我想报告冲突,即对于一个密钥对值,如果报告了多个冲突值,那么这应该是我生成的数据帧的一部分。理想情况下,我生成的数据框如下所示:


c1 c2 c3   c4 c5     conflicts_cols
a  1  m    1  k1;z1  c5
b  2  j    2  k2;z2  c5
c  3  k;p  8  k3;z3  c3, c5
d  1  m    1  k1     NA

有人可以帮忙吗?谢谢!

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    部分答案:您可以绑定两个表并在按键分组后将行“挤压”在一起。然后,找到包含多个条目的单元格,这是我无法做到的问题。

    df1 <- data.frame(c1=c("a","b","c"),c2=c(1,2,3),c3=c("m",NA,"k"),c4=c(1,2,NA),c5=c("z1","z2","z3"),stringsAsFactors = F)  
    df2 <- data.frame(c1=c("d","b","c"),c2=c(1,2,3),c3=c("m","j","p"),c4=c(1,NA,8),c5=c("k1","k2","k3"),stringsAsFactors = F)  
    
    library(data.table)
    setDT(df1)
    setDT(df2)
    
    df12<- rbind(df1,df2)
    keys <- c('c1','c2')
    df_merged <- df12[,lapply(.SD,function(x) list(unique(na.omit(x)))),by=keys]
    df_merged
    #> c1 c2  c3 c4    c5
    #> 1:  a  1   m  1    z1
    #> 2:  b  2   j  2 z2,k2
    #> 3:  c  3 k,p  8 z3,k3
    #> 4:  d  1   m  1    k1 
    
    str(df_merged)
    #> Classes 'data.table' and 'data.frame':   4 obs. of  5 variables:
    #>  $ c1: chr  "a" "b" "c" "d"
    #>  $ c2: num  1 2 3 1
    #>  $ c3:List of 4
    #>   ..$ : chr "m"
    #>   ..$ : chr "j"
    #>   ..$ : chr  "k" "p"
    #>   ..$ : chr "m"
    #>  $ c4:List of 4
    #>   ..$ : num 1
    #>   ..$ : num 2
    #>   ..$ : num 8
    #>   ..$ : num 1
    #>  $ c5:List of 4
    #>   ..$ : chr "z1"
    #>   ..$ : chr  "z2" "k2"
    #>   ..$ : chr  "z3" "k3"
    #>   ..$ : chr "k1"
    #>  - attr(*, ".internal.selfref")=<externalptr>
    

    由reprex package (v0.3.0) 于 2020 年 3 月 3 日创建

    【讨论】:

      【解决方案2】:

      {powerjoin} 主要带你去那里,你只需要定义正确的格式化函数来处理冲突,这里我们定义一个我们按行应用的函数(所以我们使用rw):

      library(powerjoin)
      
      df1 <- data.frame(c1=c("a","b","c"),c2=c(1,2,3),c3=c("m",NA,"k"),c4=c(1,2,NA),c5=c("z1","z2","z3"))  
      df2 <- data.frame(c1=c("d","b","c"),c2=c(1,2,3),c3=c("m","j","p"),c4=c(1,NA,8),c5=c("k1","k2","k3"))
      
      conflict_format <- function(x,y) paste(unique(na.omit(c(x, y))), collapse = ";")
      power_full_join(df1, df2, by = "c1", conflict = rw ~ conflict_format(.x, .y))
      #>   c1 c2  c3 c4    c5
      #> 1  a  1   m  1    z1
      #> 2  b  2   j  2 z2;k2
      #> 3  c  3 k;p  8 z3;k3
      #> 4  d  1   m  1    k1
      

      由reprex package (v2.0.1) 于 2022 年 1 月 14 日创建

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-06
        • 2019-10-18
        相关资源
        最近更新 更多