R:如何总结具有不同功能的多个变量?

时间:2019-02-23 23:59:19

标签: r dplyr summarize

我有一个数据框,其中对于每个分组变量,有两种类型的变量:一组变量,我需要每组中的均值,另一组变量,我需要每组中的总和。也就是说,我想在应用某些链函数(例如filter和select之后,将两个不同的汇总函数应用于数据帧中的两个不同的变量集,因为原始问题比这更复杂)。

> head(df, 10)
   group.var  x1  x2  x3  y1  y2  y3
1          1 460 477 236  65 142 384
2          1  88 336 114  93 378  52
3          1  93 290 353 384 498  43
4          1 394 105 306 172 216 267
5          1 402 145 423 425 125 322
6          2 187 473 466 279  81 484
7          2 465 373  50 422 136  78
8          2 404 455 362 205 315  12
9          2  54 202 242 348 324 275
10         2 340 380  14 442 376 491

理想情况下,我想在同一链中两次使用dplyr的{​​{1}}函数在两个不同的操作中将summarize_at应用于变量集1和mean应用于变量2 ,但是出于明显的原因,返回的分组df无法识别第二组变量。

sum

我可以编写两个片段,它们使用> df1 <- df %>% + select(group.var, x1:xn, y1:yn) %>% # just for reference + filter(x2 != 20) %>% # just for reference + group_by(group.var) %>% + summarize_at(vars(x1:xn), mean) %>% + summarize_at(vars(y1:ym), sum) Error in is_character(x, encoding = encoding, n = 1L) : object 'y1' not found 函数进行相同的分组,选择和过滤,但汇总不同,然后使用summarize_all加入分组的df,但是我正在寻找一个更有效的方法。 我想要的最终结果是:

group.var

任何建议,最好使用 group.var x1 x2 x3 y1 y2 y3 1 1 287.4 270.6 286.4 1139 1359 1068 2 2 290.0 376.6 226.8 1696 1232 1340 dplyr

2 个答案:

答案 0 :(得分:0)

一种方法是先使用mutate,然后使用distinct

df %>%
  select(group.var, x1:x3, y1:y3) %>% 
  filter(x2 != 20) %>% 
  group_by(group.var) %>%
  mutate_at(vars(x1:x3), mean) %>%
  mutate_at(vars(y1:y3), sum) %>%
  distinct()

输出:

# A tibble: 2 x 7
# Groups:   group.var [2]
  group.var    x1    x2    x3    y1    y2    y3
      <int> <dbl> <dbl> <dbl> <int> <int> <int>
1         1  287.  271.  286.  1139  1359  1068
2         2  290   377.  227.  1696  1232  1340

另一种方法是对全部进行汇总,然后仅选择相关的组合(meanxsumy):

df %>%
  select(group.var, x1:x3, y1:y3) %>% 
  filter(x2 != 20) %>% 
  group_by(group.var) %>%
  summarise_all(funs(mean, sum)) %>%
  select(group.var, matches("x\\d_mean"), matches("y\\d_sum"))

输出:

# A tibble: 2 x 7
  group.var x1_mean x2_mean x3_mean y1_sum y2_sum y3_sum
      <int>   <dbl>   <dbl>   <dbl>  <int>  <int>  <int>
1         1    287.    271.    286.   1139   1359   1068
2         2    290     377.    227.   1696   1232   1340

如果您对名称摘要的指定感到不便,可以在末尾添加%>% rename_all(function(x) gsub("_.*", "", x))之类的内容。

最后但并非最不重要的一点是,使用purrr的方法(在此将提供与第一种方法相同的输出):

library(tidyverse)

list(c(paste0("x", 1:3)), c(paste0("y", 1:3))) %>% 
  map2(lst(mean, sum),
       ~ df %>% 
         select(group.var, x1:x3, y1:y3) %>% 
         filter(x2 != 20) %>% 
         group_by(group.var) %>% 
         summarise_at(.x, .y)
       ) %>% 
  reduce(inner_join)

请注意,上面的示例中的小数点消失了,因为tibble是这样显示的,它们仍然存在,您可以在控制台中通过在每个代码段的末尾添加%>% as.data.frame()来显示它们。

答案 1 :(得分:0)

借助 dplyr 的新 across 功能,它可以通过这种方式实现

df1 <- df %>%
 dplyr::select(group.var, x1:x3, y1:y3) %>% # just for reference
 filter(x2 != 20) %>% # just for reference
 group_by(group.var) %>%
 summarise(across(x1:x3, mean), across(y1:y3, sum))