【问题标题】:R: Using Summarize() accross() and where() with regular expressionsR:将 Summarize() 与正则表达式结合使用 accross() 和 where()
【发布时间】:2021-06-24 10:19:58
【问题描述】:

我有以下数据集:

Lines <- "id time sex Age Obs_A Obs_B Obs_C
1  1       male   90 0 0 0
1  2       male   91 0 0 0
1  3       male   92 1 1 0
2  1       female  87 0 1 1
2  2       female  88 0 1 0
2  3       female  89 0 0 1
3  1       male  50 0 1 0
3  2       male  51 1 0 0
3  3       male  52 0 0 0
4  1       female  54 0 1 0
4  2       female  55 0 1 0
4  3       female  56 0 1 0"

我想将 summarize 与正则表达式 (grepl) 结合起来,以便重新格式化以 Obs 开头的变量(例如取中位数),同时对其他变量进行其他操作。例如这样的:

TTE <- TTE %>%
      group_by(id, across(where(is.character))) %>%
      summarise(id = first(id), sex = first(sex), 
                Age = mean(Age), across(where(grepl("Obs")), mean), across(where(is.numeric), max)) %>%
      ungroup 

但是,我收到以下错误:

x argument "x" is missing, with no default

知道如何以一致的方式使用summarize()across()where()grepl()

【问题讨论】:

    标签: r grepl summarize


    【解决方案1】:

    对于dplyr,您可以使用 tidyselect 函数来选择across 中的列。

    library(dplyr)
    
    TTE %>%
      group_by(id, across(where(is.character))) %>%
      summarise(Age = mean(Age), 
                across(starts_with('Obs'), mean), 
                across(where(is.numeric), max)) %>%
      ungroup 
    
    #     id sex      Age Obs_A Obs_B Obs_C  time
    #  <int> <chr>  <dbl> <dbl> <dbl> <dbl> <int>
    #1     1 male      91 0.333 0.333 0         3
    #2     2 female    88 0     0.667 0.667     3
    #3     3 male      51 0.333 0.333 0         3
    #4     4 female    55 0     1     0         3
    

    由于您按所有字符列进行分组,因此您无需将它们包含在 across 中。

    【讨论】:

      【解决方案2】:

      正如 OP 提到的使用regex,一个选项是matches,与starts_withend_withcontains 相比,它可以采用正则表达式。此外,我们不需要使用ungroup,因为summarise 中有一个选项可以指定.groups,即即使我们在summarise 之后使用ungroup,也会出现可以避免的警告消息如果我们指定.groups

      library(dplyr)
      TTE %>%
        group_by(id, across(where(is.character))) %>%
        summarise(Age = mean(Age), 
                  across(matches('^[Oo]bs'), mean), 
                  across(where(is.numeric), max), .groups = 'drop')
      

      -输出

      # A tibble: 4 x 7
           id sex      Age Obs_A Obs_B Obs_C  time
        <int> <chr>  <dbl> <dbl> <dbl> <dbl> <int>
      1     1 male      91 0.333 0.333 0         3
      2     2 female    88 0     0.667 0.667     3
      3     3 male      51 0.333 0.333 0         3
      4     4 female    55 0     1     0         3
      

      请注意,where 主要用于检查列的值,而不是用于列名。为此,我们需要使用 select-helpers

      【讨论】:

        猜你喜欢
        • 2011-08-14
        • 1970-01-01
        • 2012-03-03
        • 1970-01-01
        • 1970-01-01
        • 2014-02-25
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多