【问题标题】:Create a list column of unique values from other columns in a grouped tibble从分组 tibble 中的其他列创建唯一值的列表列
【发布时间】:2021-08-23 08:15:27
【问题描述】:

我有一个小标题,其中我有一些字符列和一个列表列,其中包含仅在某些行中的附加字符,否则为空白。 每次使用此分析时,字符列的数量可能会发生变化,但命名保持一致 - 它们始终以 C 开头(例如 C1L、C1H 等)。

示例数据集:

exemplar = tibble(group = c(rep("group1", 5), rep("group2",5)),
                  char1 = letters[1:10],
                  char2 = letters[2:11],
                  char3 = letters[3:12],
                  extra = list("",
                               "",
                               "",
                               "",
                               "",
                               list("x","y"),
                               "",
                               "",
                               "",
                               "")
                  )

但在“实时”使用中,可能有 2、4、6 列,但“char#”列有很多。

我正在尝试添加一个列表列,其中包含 char+extra 列中所有唯一值的列表或字符向量。 我可以按行做,但我需要为每个组做。 所需输出示例:

# A tibble: 10 x 6
   group  char1 char2 char3 extra      unique   
   <chr>  <chr> <chr> <chr> <list>     <list>   
 1 group1 a     b     c     <chr [1]>  <chr [7]>
 2 group1 b     c     d     <chr [1]>  <chr [7]>
 3 group1 c     d     e     <chr [1]>  <chr [7]>
 4 group1 d     e     f     <chr [1]>  <chr [7]>
 5 group1 e     f     g     <chr [1]>  <chr [7]>
 6 group2 f     g     h     <list [2]> <chr [9]>
 7 group2 g     h     i     <chr [1]>  <chr [9]>
 8 group2 h     i     j     <chr [1]>  <chr [9]>
 9 group2 i     j     k     <chr [1]>  <chr [9]>
10 group2 j     k     l     <chr [1]>  <chr [9]>

每个“组 1”行在 unique 列中都有 c("a", "b", "c", "d", "e", "f", "g")。 每个 'group 2' 行在unique 中都有 c("f", "g", "h", "i", "j", "k", "l", "x", "y")列。

我尝试过的事情:

> exemplar %>% group_by(group) %>% mutate(unique = unique(select(., starts_with("c"), "extra")))

Adding missing grouping variables: `group`
Error: Problem with `mutate()` input `unique`.
x Input `unique` can/'t be recycled to size 5.

> exemplar %>% 
+   mutate(unique = pmap_chr(
+     .l = select(., starts_with("c"), "extra"),
+     .f = function(...) unique(...)
+   )
+ )

Error: Problem with `mutate()` input `unique`.
x argument "x" is missing, with no default


> exemplar %>% 
+   mutate(unique = pmap_chr(
+     .l = select(., starts_with("c"), "extra"),
+     .f = function(...) unique(...)
+   )
+ )
 Error: Problem with `mutate()` input `unique`.
x argument "x" is missing, with no default

我觉得我完全错过了一个简单的方法来做到这一点 - 我应该更早地取消列出“额外”列吗?鉴于要包含的列数可变,我是否应该创建一个选择向量来使用而不是使用 select(., ...) 就地执行它?我是否需要分几步完成,然后丢弃不需要的列?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我认为以下代码可能会满足您的要求。诀窍是组合来自不同列的值,其中一些包含字符,而另一个包含“列表”。因此,第一步是从两种类型的列中提取信息作为向量(使用c_across(starts_with("c"))unlist(extra))广告将它们组合成一个向量,您可以在该向量上工作。

    exemplar %>%
      group_by(group) %>%
      mutate(unique = list( # Makes sure that the new column is a "list"
        unique(             # Get the "unique" values
          c(                # Combine results from two types of columns
            c_across(       # First extract the "char" columns into a vector 
              starts_with("c")),
            unlist(extra))  # Then extract the "extra" column into a vector
        )
      )) %>%
      ungroup()
    

    这个命令的结果如下

    # A tibble: 10 × 6
       group  char1 char2 char3 extra      unique    
       <chr>  <chr> <chr> <chr> <list>     <list>    
     1 group1 a     b     c     <chr [1]>  <chr [8]> 
     2 group1 b     c     d     <chr [1]>  <chr [8]> 
     3 group1 c     d     e     <chr [1]>  <chr [8]> 
     4 group1 d     e     f     <chr [1]>  <chr [8]> 
     5 group1 e     f     g     <chr [1]>  <chr [8]> 
     6 group2 f     g     h     <list [2]> <chr [10]>
     7 group2 g     h     i     <chr [1]>  <chr [10]>
     8 group2 h     i     j     <chr [1]>  <chr [10]>
     9 group2 i     j     k     <chr [1]>  <chr [10]>
    10 group2 j     k     l     <chr [1]>  <chr [10]>
    

    对于第 1 组,结果是

    [[1]]
    [1] "a" "b" "c" "d" "e" "f" "g" "" 
    

    对于第 1 组,

    [[1]]
     [1] "f" "g" "h" "i" "j" "k" "l" "x" "y" "" 
    

    【讨论】:

    • 太好了,谢谢。我错过了取消列出“额外”的步骤,而且我不熟悉 c_across() - 我想是时候阅读了。标记为已回答。
    • 不客气!老实说,我不确定c_accross 最初是打算这样使用的,它应该与rowwise 一起使用。但在你的情况下,它就像一个魅力。
    猜你喜欢
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    相关资源
    最近更新 更多