суммировать исходные данные на основе категорий расширенной таблицы

#r #dplyr #tidyr

#r #dplyr #tidyr

Вопрос:

Я хотел бы суммировать таблицу, используя dplyr. Вот как я хотел бы продолжить:

  • У меня есть data.frame, подобный этому:
  year    region week  site           species    gps_clutch
2017    sud   18     6                  au        337
2017    sud   20     10                 au        352
2017    sud   22     10                 au        352
2017    sud   24     10                 au        352
2017    sud   18     6                  aio       337
2017    sud   20     6                  aio       352
2017    sud   22     6                  au        352
2018    sud   20     6                  au        337
2018    sud   20     10                 au        352
2018    sud   22     10                 au        352
2018    sud   22     10                 aio       352
2018    sud   22     6                  au        352
2017    nor   19     5                  au        337
2017    nor   21     2                  au        352
2017    nor   23     5                  au        352
2017    nor   25     2                  au        352
2017    nor   19     5                  aio       337
2017    nor   25     5                  aio       352
2017    nor   19     5                  au        337
2018    nor   21     2                  aio       352
2018    nor   23     5                  aio        352
2018    nor   25     2                  au        352
2018    nor   23     5                  aio       337
2018    nor   23     5                  au       352
  
  • Я хотел бы подсчитать количество «gps_clutch» для каждого года, региона, сайта, недели и расширить это число на все возможные недели, записанные для каждого региона. Я объясняю: в регионе «юг» я отбирал данные за 18, 20, 22, 24 недели, а в регионе «север» — за 19, 21, 23, 25 недели. Я хотел бы преобразовать неявные отсутствующие значения в «0», но только для недель (вложенных в регионы), которые были отобраны. Я не хочу расширять таким образом, чтобы получить строку за 19-ю неделю в регионе «sud», потому что этот регион не был выбран на этой конкретной неделе.

этот код хорошо работает для расширения сетки, как мне бы хотелось:

 dat %>%
  group_by(region) %>%
  expand(year,site, species,week)
  

следующий код также работает для получения значений count, но не расширяет сетку так, как я хочу (я получаю только список недель, за которые я что-то наблюдал за каждым годом, а не общее количество недель, отобранных за оба года). Это означает, что если в «sud» «2017» у меня есть записи только за 20 и 22 недели, сетка не будет расширена до 18 и 24 недель :

 field_subsetnord %>%
  group_by(year,region,site,species,week) %>%
  summarise(count_clutch=length(gps_clutch)) %>% 
  complete(week,nesting(year,sites,species), fill = list(count_clutch = 0))
  

это таблица, которую я хотел бы получить в конце:

  year    region week  site           species    count
2017     sud    18     6             au         1
2017     sud    20     6             au         0
2017     sud    22     6             au         1
2017     sud    24     6             au         0

2017     sud    18     6             aio        1
2017     sud    20     6             aio        1
2017     sud    22     6             aio        0
2017     sud    24     6             aio        0

2017     sud    18     10            au         0
2017     sud    20     10            au         1
2017     sud    22     10            au         1
2017     sud    24     10            au         1

2017     sud    18     10            aio        0
2017     sud    20     10            aio        0
2017     sud    22     10            aio        0
2017     sud    24     10            aio        0

2018     sud    18     6             au        0
2018     sud    20     6             au        1
2018     sud    22     6             au        1
2018     sud    24     6             au        0

2018     sud    18     6             aio       0
2018     sud    20     6             aio       0
2018     sud    22     6             aio       0 
2018     sud    24     6             aio       0

2018     sud    18     10            au        0
2018     sud    20     10            au        1
2018     sud    22     10            au        1
2018     sud    24     10            au        0

2018     sud    18     10            aio       0
2018     sud    20     10            aio       0
2018     sud    22     10            aio       1
2018     sud    24     10            aio       0

and so on for 2018...
  

любые предложения по смешиванию этих двух кодов были бы оценены 🙂

Комментарии:

1. Вы можете указать week = 18:24 , чтобы указать значения, которые следует расширить. Из приведенного вами объяснения я не совсем уверен, это то, что вы имеете в виду. Пожалуйста, сделайте примеры более воспроизводимыми, предоставив данные в воспроизводимом формате и включив все выборки (например, 18 для sud отсутствует в показываемых вами данных)

2. Я просто соответствующим образом отредактировал свой вопрос

Ответ №1:

Вы так близки со своими двумя подходами. По сути, их просто нужно объединить, чтобы получить то, что вам нужно. 🙂

Сначала сгруппируйте по регионам, а затем complete() сначала набор данных, затем перегруппируйте по всем переменным и summarise() . Поскольку gps_clutch теперь в нем будут отсутствовать значения, вы можете суммировать не пропущенные значения (через !is.na ) в summarise() инструкции для подсчета сцеплений.

 dat %>%
    group_by(region) %>%
    complete(year, site, species, week) %>% 
    group_by(year, region, site, species, week) %>%
    summarise(count_clutch = sum( !is.na(gps_clutch) ) )

# A tibble: 64 x 6
# Groups:   year, region, site, species [16]
    year region  site species  week count_clutch
   <int> <fct>  <int> <fct>   <int>        <int>
 1  2017 nor        2 aio        19            0
 2  2017 nor        2 aio        21            0
 3  2017 nor        2 aio        23            0
 4  2017 nor        2 aio        25            0
 5  2017 nor        2 au         19            0
 6  2017 nor        2 au         21            1
 7  2017 nor        2 au         23            0
 8  2017 nor        2 au         25            1
 9  2017 nor        5 aio        19            1
10  2017 nor        5 aio        21            0
# ... with 54 more rows
  

Комментарии:

1. действительно! спасибо за вашу помощь. Есть кое-что, чего я действительно не могу понять, хотя это то, что мой скрипт работает, только если мои переменные передаются «как.character». Если они являются факторами, это больше не работает. Так ли это должно быть?

2. @user3016665 Факторы, безусловно, могут вызвать трудности в некоторых случаях. Например, иногда они преобразуются для отображения их индекса (целого числа) вместо символьного значения. В примере, который я показываю выше, используются коэффициенты для «региона» и «вида», и, похоже, это сработало нормально (похоже, я использую версии разработчиков как dplyr, так и tidyr).

3. последний вопрос, если я хотел бы получить как count_clutch (как в примере) для year> region> site> sites> week, так и другой столбец, который учитывал бы группу, но останавливался на уровне сайта (это соответствовало бы сумме за переменную week). Как бы мне включить это в тот же код. Должен ли я добавить еще один «group_by», чтобы сделать это другое количество?

4. @user3016665 Я не совсем уверен, что понимаю, но summarise() всегда удаляет «последнюю» группирующую переменную. Итак, в конце канала в моем ответе все сгруппировано по всему, кроме недели (поскольку данные сейчас находятся на уровне недели). Если бы вы хотели затем добавить переменную для представления общего количества недель с клатчами, вы могли бы сделать что-то вроде %>% mutate(nweek = sum( count_clutch != 0) ) . Для суммирования по неделям вместо добавления столбца сводки используйте summarise() .