Суммировать подгруппы с dplyr - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь суммировать подгруппы с помощью dplyr, используя mutate, но это означает, что мне нужно знать каждую группу строк, чтобы создать условное выражение. Идея состоит не в том, чтобы изменять текущую группировку, как показано в приведенном ниже коде:

mutate(mtcars, cond_disp = ifelse(vs==1,sum(disp[vs==1]),sum(disp[vs==0])))

Есть ли метод Dynami c для достижения этой цели?

Ответы [ 2 ]

2 голосов
/ 14 июля 2020

Вы можете сделать это с помощью group_by(vs) и summarise. Но как хотелось бы вот версия с mutate.

library(tidyverse)

mtcars %>% 
  group_by(vs) %>% 
  #summarise(cond_disp = sum(disp))
  mutate(cond_disp = sum(disp))
#> # A tibble: 32 x 12
#> # Groups:   vs [2]
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb cond_disp
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>     <dbl>
#>  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4     5529.
#>  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4     5529.
#>  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1     1854.
#>  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1     1854.
#>  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2     5529.
#>  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1     1854.
#>  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4     5529.
#>  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2     1854.
#>  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2     1854.
#> 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4     1854.
#> # … with 22 more rows
1 голос
/ 14 июля 2020

dplyr::mutate() будет принимать несколько строк в качестве входных данных для функций в правой части уравнения (й), которые являются аргументами для mutate(). Как отмечено в комментариях, можно использовать group_by(), чтобы разбить входные данные в функциях правой части на подгруппы. Это устраняет необходимость в условных логах c в mutate(), как указано в исходном вопросе.

Мы проиллюстрируем это, вычислив cond_disp из исходного сообщения и включив n для подсчета числа строк, включенных в сводные данные.

mtcars %>% group_by(vs) %>% 
     mutate(cond_disp = sum(disp),
            n = n()) -> result
result[,c("vs","n","cond_disp","disp")]


# A tibble: 32 x 4
# Groups:   vs [2]
      vs     n cond_disp  disp
   <dbl> <int>     <dbl> <dbl>
 1     0    18     5529.  160 
 2     0    18     5529.  160 
 3     1    14     1854.  108 
 4     1    14     1854.  258 
 5     0    18     5529.  360 
 6     1    14     1854.  225 
 7     0    18     5529.  360 
 8     1    14     1854.  147.
 9     1    14     1854.  141.
10     1    14     1854.  168.
# … with 22 more rows

Подход mutate() полезен, когда нужно вычислить процентные значения построчно, где знаменатель процента представляет собой сумму столбца в комбинации по группам. Чтобы проиллюстрировать это, мы вычислим процент общего смещения для V-образных двигателей по сравнению с прямыми двигателями, распечатаем результаты и напечатаем сумму pct_disp, чтобы проиллюстрировать, что для V-двигателей она равна 100.

mtcars %>% group_by(vs) %>% 
     mutate(pct_disp = 100* disp / sum(disp),
            n = n()) -> result
result[result$vs==0,c("vs","n","disp","pct_disp")]
sum(result$pct_disp[result$vs==0])


# A tibble: 18 x 4
# Groups:   vs [1]
      vs     n  disp pct_disp
   <dbl> <int> <dbl>    <dbl>
 1     0    18  160      2.89
 2     0    18  160      2.89
 3     0    18  360      6.51
 4     0    18  360      6.51
 5     0    18  276.     4.99
 6     0    18  276.     4.99
 7     0    18  276.     4.99
 8     0    18  472      8.54
 9     0    18  460      8.32
10     0    18  440      7.96
11     0    18  318      5.75
12     0    18  304      5.50
13     0    18  350      6.33
14     0    18  400      7.23
15     0    18  120.     2.18
16     0    18  351      6.35
17     0    18  145      2.62
18     0    18  301      5.44
> sum(result$pct_disp[result$vs==0])
[1] 100

Когда следует Использование summarize ()

dplyr::summarise() полезно, если вы хотите суммировать данные без добавления дополнительных столбцов во фрейм входных данных в конвейере. Результатом summarise() является одна строка для каждой комбинации переменных в спецификации group_by() в конвейере и столбец (столбцы) для обобщенных данных.

mtcars %>% group_by(vs) %>% 
     summarise(cond_disp = sum(disp),
            n = n()) 
# A tibble: 2 x 3
     vs cond_disp     n
  <dbl>     <dbl> <int>
1     0     5529.    18
2     1     1854.    14

построчные вычисления

Если нужно использовать функции R для вычисления значений по столбцам в строке, можно использовать функцию rowwise(), чтобы предотвратить использование mutate() нескольких строк в функциях с правой стороны уравнений в пределах mutate().

Для иллюстрации просуммируем значения vs, am. Обратите внимание, что результат n = n() на выходе равен 1 для каждой напечатанной строки.

mtcars %>% rowwise(.) %>% 
     mutate(cond_binary = sum(vs,am),
            n = n()) -> result
result[,c("vs","am","n","cond_binary")]


# A tibble: 32 x 4
# Rowwise: 
      vs    am     n cond_binary
   <dbl> <dbl> <int>       <dbl>
 1     0     1     1           1
 2     0     1     1           1
 3     1     1     1           2
 4     1     0     1           1
 5     0     0     1           0
 6     1     0     1           1
 7     0     0     1           0
 8     1     0     1           1
 9     1     0     1           1
10     1     0     1           1
# … with 22 more rows
...