我可以在现有变量同时使用summarise_at的同时添加其他变量吗?

时间:2019-11-15 23:08:03

标签: r dplyr

假设我有一个分组的数据框:

> mtcars %>% 
+   group_by(cyl) %>% 
+   summarise(blah = mean(disp))
# A tibble: 3 x 2
    cyl  blah
  <dbl> <dbl>
1     4  105.
2     6  183.
3     8  353.

然后假设我想对一些现有变量求和:

> mtcars %>% 
+   group_by(cyl) %>% 
+   summarise_at(vars(vs:carb), sum)
# A tibble: 3 x 5
    cyl    vs    am  gear  carb
  <dbl> <dbl> <dbl> <dbl> <dbl>
1     4    10     8    45    17
2     6     4     3    27    24
3     8     0     2    46    49

但是,如果我想将两个摘要命令加在一起,则不能:

> mtcars %>% 
+   group_by(cyl) %>% 
+   summarise_at(vars(vs:carb), sum) %>% 
+   summarise(blah = mean(disp))
Error in mean(disp) : object 'disp' not found

在dplyr链中使用了group_by()之后,我如何才能通过summarise()添加新功能,以及如何使用summarise_at(vars(vs:carb), sum)对现有功能进行汇总?

4 个答案:

答案 0 :(得分:3)

(目前)我唯一想到的方法是在第一个摘要之前存储数据,然后运行两个摘要动词,然后将它们加入分组变量中。例如:

library(dplyr)

grouped_data <- group_by(mtcars, cyl)
left_join(
  summarize(grouped_data, blah = mean(disp)),
  summarize_at(grouped_data, vars(vs:carb), sum),
  by = "cyl")
# # A tibble: 3 x 6
#     cyl  blah    vs    am  gear  carb
#   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     4  105.    10     8    45    17
# 2     6  183.     4     3    27    24
# 3     8  353.     0     2    46    49

答案 1 :(得分:1)

您可以left_join处理summarise产生的数据框。

library(dplyr)

data(mtcars)

mtcars %>% 
  group_by(cyl) %>% 
  summarise_at(vars(vs:carb), sum) %>% 
  left_join(mtcars %>% group_by(cyl) %>% summarise(blah = mean(disp)))
#Joining, by = "cyl"
## A tibble: 3 x 6
#    cyl    vs    am  gear  carb  blah
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1     4    10     8    45    17  105.
#2     6     4     3    27    24  183.
#3     8     0     2    46    49  353.

答案 2 :(得分:1)

我要做的是首先使用mutate_at,以便其他列不会折叠,然后将summarise_atmean一起用于所有列。

library(dplyr) 

mtcars %>% 
   group_by(cyl) %>% 
   mutate_at(vars(vs:carb), sum) %>%
   summarise_at(vars(vs:carb, disp), mean)

#    cyl    vs    am  gear  carb  disp
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1     4    10     8    45    17  105.
#2     6     4     3    27    24  183.
#3     8     0     2    46    49  353.

答案 3 :(得分:0)

这是一种方法,我们需要先定义一个辅助函数,它仅在管道链中起作用,并使用 dplyr 中未导出的函数,尽管这样可能会中断一天。

.at <- function(.vars, .funs, ...) {
  # make sure we are in a piped call
  in_a_piped_fun <- exists(".",parent.frame()) &&
    length(ls(envir=parent.frame(), all.names = TRUE)) == 1
  if (!in_a_piped_fun)
    stop(".at() must be called as an argument to a piped function")
  # borrow code from summarize_at
  .tbl <- try(eval.parent(quote(.)))
  dplyr:::manip_at(
    .tbl, .vars, .funs, rlang::enquo(.funs), rlang:::caller_env(),
    .include_group_vars = TRUE, ...)
}

library(dplyr, warn.conflicts = FALSE)
mtcars %>%
  summarize(!!!.at(vars(vs:carb), sum),  blah = mean(disp))
#>   vs am gear carb     blah
#> 1 14 13  118   90 230.7219

reprex package(v0.3.0)于2019-11-17创建