Что такое метод **tidyverse** для разделения df на несколько столбцов?

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

Вот как это сделать, используя split() из base:

library(tidyverse)
#> Loading tidyverse: ggplot2
#> Loading tidyverse: tibble
#> Loading tidyverse: tidyr
#> Loading tidyverse: readr
#> Loading tidyverse: purrr
#> Loading tidyverse: dplyr
#> Conflicts with tidy packages ----------------------------------------------
#> filter(): dplyr, stats
#> lag():    dplyr, stats

mtcars %>% 
  select(1:3) %>% 
  mutate(GRP_A = sample(LETTERS[1:2], n(), replace = TRUE),
         GRP_B = sample(c(1:2), n(), replace = TRUE)) %>% 
  split(list(.$GRP_A, .$GRP_B)) %>% 
  map(summary)
#> $A.1
#>       mpg             cyl           disp          GRP_A          
#>  Min.   :10.40   Min.   :4.0   Min.   :108.0   Length:10         
#>  1st Qu.:14.97   1st Qu.:4.5   1st Qu.:151.9   Class :character  
#>  Median :18.50   Median :7.0   Median :259.3   Mode  :character  
#>  Mean   :17.61   Mean   :6.4   Mean   :283.4                     
#>  3rd Qu.:20.85   3rd Qu.:8.0   3rd Qu.:430.0                     
#>  Max.   :24.40   Max.   :8.0   Max.   :472.0                     
#>      GRP_B  
#>  Min.   :1  
#>  1st Qu.:1  
#>  Median :1  
#>  Mean   :1  
#>  3rd Qu.:1  
#>  Max.   :1  
#> 
#> $B.1
#>       mpg             cyl           disp          GRP_A          
#>  Min.   :15.00   Min.   :4.0   Min.   : 75.7   Length:5          
#>  1st Qu.:21.00   1st Qu.:4.0   1st Qu.: 78.7   Class :character  
#>  Median :21.50   Median :4.0   Median :120.1   Mode  :character  
#>  Mean   :24.06   Mean   :5.2   Mean   :147.1                     
#>  3rd Qu.:30.40   3rd Qu.:6.0   3rd Qu.:160.0                     
#>  Max.   :32.40   Max.   :8.0   Max.   :301.0                     
#>      GRP_B  
#>  Min.   :1  
#>  1st Qu.:1  
#>  Median :1  
#>  Mean   :1  
#>  3rd Qu.:1  
#>  Max.   :1  
#> 
#> $A.2
#>       mpg             cyl             disp          GRP_A          
#>  Min.   :15.20   Min.   :4.000   Min.   : 95.1   Length:9          
#>  1st Qu.:16.40   1st Qu.:6.000   1st Qu.:160.0   Class :character  
#>  Median :18.10   Median :8.000   Median :275.8   Mode  :character  
#>  Mean   :19.84   Mean   :6.667   Mean   :234.0                     
#>  3rd Qu.:21.00   3rd Qu.:8.000   3rd Qu.:275.8                     
#>  Max.   :30.40   Max.   :8.000   Max.   :360.0                     
#>      GRP_B  
#>  Min.   :2  
#>  1st Qu.:2  
#>  Median :2  
#>  Mean   :2  
#>  3rd Qu.:2  
#>  Max.   :2  
#> 
#> $B.2
#>       mpg             cyl         disp          GRP_A          
#>  Min.   :13.30   Min.   :4   Min.   : 71.1   Length:8          
#>  1st Qu.:14.97   1st Qu.:4   1st Qu.:125.3   Class :character  
#>  Median :20.55   Median :6   Median :201.5   Mode  :character  
#>  Mean   :20.99   Mean   :6   Mean   :213.5                     
#>  3rd Qu.:23.93   3rd Qu.:8   3rd Qu.:315.5                     
#>  Max.   :33.90   Max.   :8   Max.   :360.0                     
#>      GRP_B  
#>  Min.   :2  
#>  1st Qu.:2  
#>  Median :2  
#>  Mean   :2  
#>  3rd Qu.:2  
#>  Max.   :2

Как я могу добиться того же результата, используя глагол tidyverse? Моей первоначальной мыслью было использовать purrr::by_slice(), но, видимо, это устарело.


person Tiernan    schedule 09.03.2017    source источник
comment
Есть ли причина, по которой вы не можете использовать split? Вы хотите определенно разделить или group_by тоже сработает?   -  person be_green    schedule 09.03.2017
comment
Я стараюсь не смешивать диалекты r, поэтому .$GRP_A мне не по вкусу. group_by не годится - он возвращает сгруппированный data.frame, но summary() не распознает группы.   -  person Tiernan    schedule 09.03.2017
comment
Теперь, когда я набрал его, мое предпочтение диалекту tidyverse может быть излишне придирчивым... но если бы у меня был выбор, я бы в любой день предпочел глагол tidyverse вместо split, так что я просто подумал, что посмотрю если есть что-то, что я упустил из виду.   -  person Tiernan    schedule 09.03.2017
comment
Вы можете использовать do(s=summary(.))   -  person HubertL    schedule 09.03.2017
comment
@HubertL, это хороший способ сделать это! Вы хотите отправить ответ или мне?   -  person Tiernan    schedule 10.03.2017
comment
@Tiernan Давай, спасибо   -  person HubertL    schedule 10.03.2017


Ответы (2)


dplyr 0.8.0 представил глагол, который вы искали: group_split()

Из документации:

group_split() работает как base::split(), но

  • он использует структуру группировки из group_by() и, следовательно, подлежит маске данных

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

group_keys() объясняет структуру группировки, возвращая фрейм данных, который имеет одну строку на группу и один столбец на переменную группировки.

Для вашего примера:

mtcars %>% 
  select(1:3) %>% 
  mutate(GRP_A = sample(LETTERS[1:2], n(), replace = TRUE),
         GRP_B = sample(c(1:2), n(), replace = TRUE)) %>% 
  group_split(GRP_A, GRP_B) %>% 
  map(summary)
person MartijnVanAttekum    schedule 28.07.2019

person    schedule
comment
Я прочитал здесь, что do уходит, хотя не совсем понятно, что это значит. - person aosmith; 10.03.2017
comment
Хм... Я зарегистрирую проблему в репозитории purrr github и посмотрю, смогу ли я попросить одного из разработчиков обсудить это. Спасибо за внимание @aosmith! - person Tiernan; 10.03.2017
comment
Похоже, что другие выступали за сохранение by_slice: github.com/hadley/purrr/issues/270 - person Tiernan; 10.03.2017
comment
Вы можете использовать dmap сразу после группировки. Вы получаете фрейм данных, а не список, и теряете имена строк - person FlorianGD; 10.03.2017
comment
@FlorianGD Я не получил желаемого результата, заменив dmap(.f = summary) на строку do ... и я также получил предупреждение о том, что dmap скоро будет объявлено устаревшим. - person Tiernan; 10.03.2017
comment
Проблема опубликована в репозитории dplyr: github.com/hadley/dplyr/issues/2518 - person Tiernan; 10.03.2017
comment
Вопрос отправлен в список рассылки: groups.google.com/d/msg/manipulatr/EMARFJfSvwY/BjXiY1kVDgAJ - person Tiernan; 10.03.2017