dplyr: group_by, суммировать различные столбцы и применять функцию на основе сумм сгруппированных строк?

Я пытаюсь использовать dplyr, чтобы суммировать набор данных об изобилии видов птиц в лесах, которые в некоторой степени фрагментированы.

Первый столбец, percent_cover, имеет 4 возможных значения: 10, 25, 50, 75. Затем идут десять столбцов с подсчетом видов птиц: от «разновидностей1» до «видов10».

Я хочу сгруппировать по проценту покрытия, затем просуммировать другие столбцы и вычислить эти суммы как процент от сумм четырех строк.

Добраться до сумм столбца достаточно просто:


% ›% Group_by (Percent_cover)%›% summarise_at (vars (содержит (виды)), сумма)


... но мне нужно sum / rowSum * 100. Похоже, нужна какая-то «построчная» операция.

Кроме того, из интереса, почему следующее не работает?


% ›% Group_by (Percent_cover)%›% summarise_at (vars (содержит (виды)), сумма * 100)


На этом этапе возникает соблазн вернуться к циклам for ... или сводным таблицам Excel.


person Michael Smith    schedule 28.11.2020    source источник


Ответы (1)


Чтобы использовать dplyr, попробуйте следующее:

library(dplyr)

df %>% 
  group_by(Percent_cover) %>% 
  summarise(across(contains("species"), sum)) %>%
  mutate(rs = rowSums(select(., contains("species")))) %>%
  mutate(across(contains('species'), ~./rs * 100)) -> result

result

Например, используя mtcars:

mtcars %>%
  group_by(cyl) %>%
  summarise(across(disp:wt, sum)) %>%
  mutate(rs = rowSums(select(., disp:wt))) %>%
  mutate(across(disp:wt, ~./rs * 100))

#   cyl  disp    hp  drat    wt    rs
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1     4  54.2  42.6 2.10  1.18  2135.
#2     6  58.7  39.2 1.15  0.998 2186.
#3     8  62.0  36.7 0.567 0.702 7974.
person Ronak Shah    schedule 28.11.2020
comment
Очень милый Ронак. Стоит добавить .names = "{col}_percent" к окончательному across для ясности? - person Allan Cameron; 28.11.2020
comment
Это хорошее предложение для ясности. Однако он сохранит исходные столбцы как есть и создаст новый столбец с этими новыми именами. - person Ronak Shah; 28.11.2020
comment
Да, было бы неплохо, если бы across имел возможность перезаписывать исходные столбцы без сохранения их имен. - person Allan Cameron; 28.11.2020