【问题标题】:dplyr::summarize_at – sort columns by order of variables passed, then by order of functions applieddplyr::summarize_at – 按传递的变量顺序对列进行排序,然后按应用函数的顺序
【发布时间】:2018-01-14 16:21:36
【问题描述】:

问题

通过使用dplyr::summarize_at()(或等效项),我想获得一个汇总表,其中列首先按 (G) 使用的分组变量顺序排序,然后按 (V) 传递的变量顺序,最后按 (F) 应用函数的顺序。默认顺序首先由 G 确定,然后由 F 确定,最后由 V 确定。

示例

代码:

library(purrr)
library(dplyr)

q025 <- partial(quantile, probs  = 0.025, na.rm = TRUE)
q975 <- partial(quantile, probs  = 0.975, na.rm = TRUE)

vars_to_summarize <- c("height", "mass")

my_summary <- starwars %>% 
    filter(skin_color  %in% c("gold", "green")) %>% 
    group_by(skin_color) %>% 
    summarise_at(vars_to_summarize, funs(q025, mean, q975))

结果:

my_summary
## A tibble: 2 x 7
##   skin_color height_q025 mass_q025 height_mean mass_mean height_q975 mass_q975
##        <chr>       <dbl>     <dbl>       <dbl>     <dbl>       <dbl>     <dbl>
## 1       gold     167.000      75.0         167        75      167.00      75.0
## 2      green      79.375      22.7         169        NA      204.75     110.4

所需的变量顺序应该是:

skin_color, height_q025, height_mean, height_q975, mass_q025, mass_mean, mass_q975

我想使用类似这样(非常简单)的代码:

my_summary  %>% 
    select(everything(), starts_with(vars_to_summarize))

但它不起作用。即使这段代码也不能像我预期的那样工作 (尽管这不是我寻求的通用解决方案):

my_summary  %>% 
    select(everything(),
           starts_with(vars_to_summarize[1]),
           starts_with(vars_to_summarize[2]))

很可能everything() 应该始终是select() 中的最后一个参数。

概括

说,我有:

  1. N 我传递给group_by() 的分组变量(“gr_”),
  2. L 个变量(“var_”)必须被汇总和
  3. M 要应用的摘要函数(“fun_”)。

一般来说,所需的变量顺序 在汇总表中应遵循以下模式:

gr_1, gr_2, ..., gr_N,   
var_1_fun_1, var_1_fun_2, ..., var_1_fun_M,  
var_2_fun_1, var_2_fun_2, ..., var_2_fun_M, 
...,
var_L_fun_1, var_L_fun_2, ..., var_L_fun_M

【问题讨论】:

  • 试试my_summary %&gt;% select(c(matches(vars_to_summarize[1]), matches(vars_to_summarize[2])))

标签: r sorting dplyr summarize


【解决方案1】:

我们可以使用matchesgrep

my_summary %>%
    select(grep(paste(vars_to_summarize, collapse="|"), names(.), invert = TRUE), 
           matches(vars_to_summarize[1]),
           matches(vars_to_summarize[2]))
# A tibble: 2 x 7
#    skin_color height_q025 height_mean height_q975 mass_q025 mass_mean mass_q975
#       <chr>       <dbl>       <dbl>       <dbl>     <dbl>     <dbl>     <dbl>
#1       gold     167.000         167      167.00      75.0        75      75.0
#2      green      79.375         169      204.75      22.7        NA     110.4

如果有很多列,那么另一种选择是从列名中的_ 中删除子字符串,match 中带有“vars_to_summarize”和orderselect

my_summary %>% 
   select(order(match(sub("_.*", "", names(.)), vars_to_summarize, nomatch = 0)))
# A tibble: 2 x 7
#    skin_color height_q025 height_mean height_q975 mass_q025 mass_mean mass_q975
#       <chr>       <dbl>       <dbl>       <dbl>     <dbl>     <dbl>     <dbl>
#1       gold     167.000         167      167.00      75.0        75      75.0
#2      green      79.375         169      204.75      22.7        NA     110.4

【讨论】:

  • Brilliant!!!☺ 正如我打算在变量名中包含 _ 一样,正则表达式 sub("(.*)_.*?$", "\\1", names(.)) 更合适。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2019-01-26
  • 2020-09-29
相关资源
最近更新 更多