【问题标题】:how to avoid overwriting when merging multiple datasets in r在r中合并多个数据集时如何避免覆盖
【发布时间】:2019-06-19 17:34:19
【问题描述】:

假设我有两个数据集 df1 和 df2 如下:

df1 <- data.frame(Id = c(1L,2L,3L,4L,5L,6L,7L,8L), pricetag = c("na","na","na","na","na","na","na","na"),stringsAsFactors=F)
df2 <- data.frame(Id=c(1L,2L,3L,4L), price = c(10,20,30,40), stringsAsFactors=F)

> df1
  Id pricetag
1  1       na
2  2       na
3  3       na
4  4       na
5  5       na
6  6       na
7  7       na
8  8       na
> df2
  Id price
1  1    10
2  2    20
3  3    30
4  4    40 

我正在尝试通过使用此函数匹配 id 将价格值从 df2 插入 df1。

df1$pricetag <- df2$price[match(df1$Id, df2$Id)]

提供这个:

> df1
  Id pricetag
1  1       10
2  2       20
3  3       30
4  4       40
5  5       NA
6  6       NA
7  7       NA
8  8       NA

我有第三个数据集。我正在尝试遵循相同的程序。

df3 <- data.frame(Id=c(5L,6L,7L,8L), price=c(50,60,70,80),stringsAsFactors=F)
> df3
  Id price
1  5    50
2  6    60
3  7    70
4  8    80

df1$pricetag <- df3$price[match(df1$Id, df3$Id)]

> df1
  Id pricetag
1  1       NA
2  2       NA
3  3       NA
4  4       NA
5  5       50
6  6       60
7  7       70
8  8       80

但是,它会覆盖 df1 中来自 df2 的价格信息。当我复制相同的过程时,有什么方法可以关闭此选项?

【问题讨论】:

    标签: r merge


    【解决方案1】:

    替换

    df1$pricetag <- df3$price[match(df1$Id, df3$Id)]
    

    如果您想进行 update-join(用 df3 中的数据覆盖 df1):

    idx <- match(df1$Id, df3$Id)
    idxn <- which(!is.na(idx))
    df1$pricetag[idxn] <- df3$price[idx[idxn]]
    rm(idx, idxn)
    df1
    #  Id pricetag
    #1  1       10
    #2  2       20
    #3  3       30
    #4  4       40
    #5  5       50
    #6  6       60
    #7  7       70
    #8  8       80
    

    如果你想创建一个 gap-fill-join(用 df3 中的数据填充 df1 中的 NA):

    idxg <- which(is.na(df1$pricetag))
    idx <- match(df1$Id[idxg], df3$Id)
    idxn <- which(!is.na(idx))
    df1$pricetag[idxg][idxn] <- df3$price[idx[idxn]]
    rm(idxg, idx, idxn)
    df1
    #  Id pricetag
    #1  1       10
    #2  2       20
    #3  3       30
    #4  4       40
    #5  5       50
    #6  6       60
    #7  7       70
    #8  8       80
    

    【讨论】:

      【解决方案2】:

      您可以使用is.na 函数来识别要查找的行:

      w = which(is.na(df1$pricetag))
      df1$pricetag[w] <- df3$price[match(df1$Id[w], df3$Id)]
      
        Id category pricetag
      1  1       na       10
      2  2       na       20
      3  3       na       30
      4  4       na       40
      5  5       na       50
      6  6       na       60
      7  7       na       70
      8  8       na       80
      

      data.table 包有一些更方便的语法:

      df1 <- data.frame(Id=c(1L,2L,3L,4L,5L,6L,7L,8L), category="na", stringsAsFactors=FALSE)
      
      library(data.table)
      setDT(df1); setDT(df2); setDT(df3)
      
      df1[, pricetag := NA_real_]
      for (odf in list(df2, df3)) 
        df1[is.na(pricetag), 
          pricetag := odf[.SD, on=.(Id), x.price]
      ][]
      
         Id category pricetag
      1:  1       na       10
      2:  2       na       20
      3:  3       na       30
      4:  4       na       40
      5:  5       na       50
      6:  6       na       60
      7:  7       na       70
      8:  8       na       80
      

      这种合并称为“更新连接”。

      【讨论】:

        【解决方案3】:

        我们可以使用 {powerjoin} :

        library(powerjoin)
        library(tidyverse)
        
        df1 %>% 
          # have all price cols be named the same
          rename(price = pricetag) %>%
          # make regular numeric NAs from your "na" characters
          mutate_at("price", as.numeric) %>% 
          # fetch Id cols and incorporate them
          power_left_join(df2, "Id", conflict = coalesce_xy) %>% 
          power_left_join(df3, "Id", conflict = coalesce_xy)
        
        #   Id price
        # 1  1    10
        # 2  2    20
        # 3  3    30
        # 4  4    40
        # 5  5    50
        # 6  6    60
        # 7  7    70
        # 8  8    80
        

        【讨论】:

          猜你喜欢
          • 2015-03-20
          • 2020-11-21
          • 1970-01-01
          • 1970-01-01
          • 2011-07-31
          • 2015-07-10
          • 1970-01-01
          • 2015-01-13
          相关资源
          最近更新 更多