【问题标题】:Merging Tibbles, but overriding missing values合并 Tibbles,但覆盖缺失值
【发布时间】:2018-05-27 21:07:25
【问题描述】:

我正在使用full_join 加入以下两个小标题:

library(dplyr)
library(tibble)

tibble(id=c(1:2, NA), b = c("mouse", "cat", "fish"), c = 6:8) %>% 
full_join(tibble(id=1:3, b = c("mouse", "", "fish"), c = 6:8))

这会给我:

A tibble: 5 x 3
 id     b     c
 1 mouse     6
 2   cat     7
NA  fish     8
 2           7
 3  fish     8

不过,理想情况下,我想得到类似的东西:

A tibble: 5 x 3
 id     b     c
 1 mouse     6
 2   cat     7
 3  fish     8

所有 NA 或缺失值都被替换为具有更多信息的更“高级”行。我该怎么做?

【问题讨论】:

    标签: r join merge na tibble


    【解决方案1】:

    假设这两个tibbles被称为ab,我们可以首先将任何被认为是缺失值的字符替换为NA(在这种情况下,“”被认为是NA)。 b[b == ""] <- NA 是一种快速的方法。

    之后,我们可以通过您知道完整的列(在本例中为列c)执行full_join。最后,我们可以使用coalesce 函数将NA 替换为两个关联的列。 dat 是最终输出。

    library(dplyr)
    library(tibble)
    
    # Create example data frame
    a <- tibble(id=c(1:2, NA), b = c("mouse", "cat", "fish"), c = 6:8)
    b <- tibble(id=1:3, b = c("mouse", "", "fish"), c = 6:8)
    
    # Replace "" with NA
    b[b == ""] <- NA
    
    # Conduct full_join by c
    dat <- full_join(a, b, by = "c") %>%
      # Use coalesce to merge column and replace NA
      mutate(id = coalesce(.$id.x, .$id.y),
             b = coalesce(.$b.x, .$b.y)) %>%
      # Select columns
      select(id, b, c)
    
    # View the results
    dat
    # # A tibble: 3 x 3
    #      id b         c
    #   <int> <chr> <int>
    # 1     1 mouse     6
    # 2     2 cat       7
    # 3     3 fish      8
    

    【讨论】:

      【解决方案2】:

      关于您的具体示例,我认为您的问题是如何组合两个小标题,而每个小标题都有不同的不完整观察结果(行)。在进行full_join 之前,您可以使用filter_all 稍微清除您的数据。

      filter_all(all_vars( (!is.na(.)) & (.!="") ) )
      

      所以这意味着选择满足两个条件的行(对于所有变量):不是 NA 和“”。

      tb1 <- tibble(id=c(1:2, NA), b = c("mouse", "cat", "fish"), c = 6:8) 
      tb1 <- tb1%>% filter_all(all_vars((!is.na(.))&(.!="")))
      > tb1
      # A tibble: 3 x 3
         id    b         c
        <int> <chr> <int>
      1     1 mouse     6
      2     2 cat       7
      

      对花药组做同样的事情,然后做full_join

      tb2 <- tibble(id=1:3, b = c("mouse", "", "fish"), c = 6:8)
      tb2 <- tb2 %>% filter_all(all_vars((!is.na(.))&(.!="")))
      full_join(tb1,tb2)
      Joining, by = c("id", "b", "c")
      # A tibble: 3 x 3
           id b         c
        <int> <chr> <int>
      1     1 mouse     6
      2     2 cat       7
      3     3 fish      8
      

      【讨论】:

        【解决方案3】:

        我们可以使用我的包safejoin中的safe_left_join,并使用 dplyr::coalesce 处理列冲突。

        # devtools::install_github("moodymudskipper/safejoin")
        library(safejoin)
        
        a <- tibble(id=c(1:2, NA), b = c("mouse", "cat", "fish"), c = 6:8)
        b <- tibble(id=1:3, b = c("mouse", "", "fish"), c = 6:8)
        

        解决方案:

        b[b==""] <- NA
        safe_left_join(a, b, by = "c", conflict = coalesce)
        # # A tibble: 3 x 3
        #      id b         c
        #   <int> <chr> <int>
        # 1     1 mouse     6
        # 2     2 cat       7
        # 3     3 fish      8
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-09
          • 1970-01-01
          • 2012-12-25
          • 2014-07-19
          • 2019-09-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多