Доступ к группирующим переменным в purrr :: map () с вложенными фреймами данных - PullRequest
0 голосов
/ 19 декабря 2018

Я использую tidyr::nest() в сочетании с purrr::map() (-family), чтобы сгруппировать data.frame в группы, а затем сделать некоторые интересные вещи с каждым подмножеством.Рассмотрите следующий пример, и , пожалуйста, игнорируйте тот факт, что мне не нужны nest() и map(), чтобы сделать это (это упрощенный пример):

library(dplyr)
library(purrr)
library(tidyr)

mtcars %>% 
  group_by(cyl) %>%
  nest() %>%
  mutate(
    wt_mean = map_dbl(data,~mean(.x$wt))
  )

# A tibble: 8 x 4
    cyl  gear data               cly2
  <dbl> <dbl> <list>            <dbl>
1     6     4 <tibble [4 x 9]>      6
2     4     4 <tibble [8 x 9]>      4
3     6     3 <tibble [2 x 9]>      6
4     8     3 <tibble [12 x 9]>     8
5     4     3 <tibble [1 x 9]>      4
6     4     5 <tibble [2 x 9]>      4
7     8     5 <tibble [2 x 9]>      8
8     6     5 <tibble [1 x 9]>      6

Обычно, когдаЯ делаю этот тип операции, мне нужен доступ к переменной группировки (в данном случае cyl) в пределах map().Но эти группирующие переменные отображаются в виде векторов с длиной, соответствующей количеству строк во вложенном фрейме данных, и, следовательно, не поддаются легко.

Можно ли выполнить следующую операцию?Я бы хотел, чтобы среднее значение wt было разделено на количество цилиндров (cyl) на группу (т. Е. Ряд).

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  mutate(
    wt_mean = map_dbl(data,~mean(.x$wt)/cyl)
  )


Error in mutate_impl(.data, dots) : 
  Evaluation error: Result 1 is not a length 1 atomic vector.

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

В новой версии dplyr 0-8-0 теперь вы можете использовать group_map, что я считаю очень удобным для этого варианта использования.Это пример от пользователя github @ yutannihilation

library(dplyr, warn.conflicts = FALSE)

mtcars %>% 
  group_by(cyl) %>%
  group_map(function(data, group_info) {
    tibble::tibble(wt_mean = mean(data$wt) / group_info$cyl)
  })
0 голосов
/ 19 декабря 2018

Возьмите cyl из вызова map:

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  mutate(
    wt_mean = map_dbl(data, ~mean(.x$wt)) / cyl
  )

# A tibble: 8 x 4
    cyl  gear data              wt_mean
  <dbl> <dbl> <list>              <dbl>
1     6     4 <tibble [4 x 9]>    0.516
2     4     4 <tibble [8 x 9]>    0.595
3     6     3 <tibble [2 x 9]>    0.556
4     8     3 <tibble [12 x 9]>   0.513
5     4     3 <tibble [1 x 9]>    0.616
6     4     5 <tibble [2 x 9]>    0.457
7     8     5 <tibble [2 x 9]>    0.421
8     6     5 <tibble [1 x 9]>    0.462

map_dbl видит cyl как вектор длины 8, потому что nest удаляет группы из data.frame.Использование cyl в вызове функции map_* (как в примере с OP) приводит к 8 векторам длины 8.

2 других подхода:

Оба с тем же результатом, что и выше, но сохраняютсгруппированные переменные в вызове map_*, согласно спецификациям OP:

Повторная группировка после nest

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  group_by(cyl, gear) %>%
  mutate(wt_mean = map_dbl(data,~mean(.x$wt)/cyl))

map2 для итерации по cyl

mtcars %>% 
  group_by(cyl,gear) %>%
  nest() %>%
  mutate(wt_mean = map2_dbl(data, cyl,~mean(.x$wt)/ .y))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...