【问题标题】:How to drop duplicated column names in nested tibbles before unnesting如何在取消嵌套之前在嵌套的小标题中删除重复的列名
【发布时间】:2021-11-18 02:00:04
【问题描述】:

我有一个包含(嵌套)小标题的列的小标题。嵌套的小标题有重复的数据(相同的名称,相同的值):

df <- tibble(id = 1:2, data = list(tibble(id = 1, var1 = "a", var2 = "b"), tibble(id = 2, var1 = "c", var2 = "d")))

df

# # A tibble: 2 x 2
#      id data            
#   <int> <list>          
# 1     1 <tibble [1 x 3]>
# 2     2 <tibble [1 x 3]>  

调用df %&gt;% unnest(data) 会导致

Error: Names must be unique..

我想编写一个函数来预先删除这些列,但不知道如何。我的目标是运行以使用以下内容:

df %>% 
  drop_duplicated_cols(data) %>% 
  unnest(data)

这会导致:

#> # A tibble: 2 x 4
#>      id var1  var2 
#>   <int> <chr> <chr>
#> 1     1 a     b    
#> 2     2 c     d    

【问题讨论】:

    标签: r tidyr unnest


    【解决方案1】:

    你可以使用unnest_longer

    library(tidyverse)
    df %>%
      unnest_longer(data)
    

    给出:

    # A tibble: 2 x 2
         id data$id $var1 $var2
      <int>   <dbl> <chr> <chr>
    1     1       1 a     b    
    2     2       2 c     d 
    

    如果要真正转换tibble列,也可以使用:

    df %>%
      left_join(reduce(df$data, bind_rows), by = "id")
    

    给出:

    # A tibble: 2 x 4
         id data             var1  var2 
      <dbl> <list>           <chr> <chr>
    1     1 <tibble [1 x 3]> a     b    
    2     2 <tibble [1 x 3]> c     d   
    

    然后你可以从那里例如取消选择数据列。

    【讨论】:

      【解决方案2】:

      unnest 中有一个 names_repair 参数。默认情况下,它是"check_unique",这会导致错误。如果我们将其更改为另一个选项,即“唯一”,它将使与.. 重复的列后跟一些数字,然后我们使用select 来获取不重复的列

      library(dplyr)
      library(tidyr)
      library(stringr)
      df %>%
          unnest(data, names_repair = "unique") %>%
          select(names(.)[!duplicated(str_remove(names(.), "\\.+.*"))]) %>%
          rename_with(~ str_remove(., "\\.+.*"), contains(".."))
      

      -输出

      # A tibble: 2 x 3
           id var1  var2 
        <int> <chr> <chr>
      1     1 a     b    
      2     2 c     d   
      

      或者避免警告的另一种选择是通过使用map 循环删除list 中的重复列

      library(purrr)
      out <- df %>% 
         mutate(data = map(data, ~ .x %>% 
                  select(-any_of(names(df))))) %>%
         unnest(data)
      out
      # A tibble: 2 x 3
           id var1  var2 
        <int> <chr> <chr>
      1     1 a     b    
      2     2 c     d    
      > str(out)
      tibble [2 × 3] (S3: tbl_df/tbl/data.frame)
       $ id  : int [1:2] 1 2
       $ var1: chr [1:2] "a" "c"
       $ var2: chr [1:2] "b" "d"
      

      注意:两种解决方案都给出了 OP 帖子中的预期输出以及结构

      【讨论】:

        【解决方案3】:

        df$data 行组合在一起并与原始数据框连接。

        library(dplyr)
        
        left_join(df %>% select(-data), bind_rows(df$data), by = 'id')
        
        #     id var1  var2 
        #  <dbl> <chr> <chr>
        #1     1 a     b    
        #2     2 c     d    
        

        【讨论】:

          猜你喜欢
          • 2019-05-01
          • 2012-08-05
          • 2021-12-04
          • 2018-10-17
          • 1970-01-01
          • 1970-01-01
          • 2021-02-27
          • 2020-09-06
          • 2022-01-15
          相关资源
          最近更新 更多