Подведите итоги, используя различные группирующие переменные в dplyr - PullRequest
3 голосов
/ 08 мая 2020

Я хотел бы резюмировать фрейм данных, используя разные группирующие переменные для каждой сводки, которую нужно выполнить sh. В качестве примера у меня есть три переменные (x1, x2, x3). Я хочу сгруппировать фрейм данных по x1 и получить количество наблюдений в этой группе, но я хочу сделать то же самое для x2 и x3.

Я хотел бы выполнить sh это с тем же блоком трубопровод, но пока единственное решение, которое я придумал, - это сохранить несколько выходов для каждой отдельной группировки, которую я хотел бы.

Чтобы воспроизвести мой фрейм данных:

x1 <- c(0,1,1,2,2,3,3,3,4,4,5,6,6,7,8,9,9,10)
x2 <- c(0,0,1,1,0,1,2,0,0,2,1,0,3,4,2,3,0,3)
x3 <- c(0,1,0,1,2,2,1,3,4,2,4,6,3,3,6,6,9,7)
df <- data.frame(x1,x2,x3)

Мой ожидаемый результат будет выглядеть что-то вроде этого, где x - это минимальное и максимальное число для переменных, а n_x1-3 - это количество наблюдений с определенным c числом и с использованием этой переменной в качестве группирующей переменной:

       x     n_x1     n_x2     n_x3
 1     0        1        7        2
 2     1        2        4        3
 3     2        2        3        3
 4     3        3        3        3
 5     4        2        1        2
 6     5        1       NA       NA
 7     6        2       NA        3
 8     7        1       NA        1
 9     8        1       NA       NA
10     9        2       NA        1
11    10        1       NA       NA

Итак далеко я придумал суммирование и группировку по каждой переменной в отдельности, а затем объединение их всех вместе в качестве последнего шага.

x1_count <- df %>%
  group_by(x1) %>%
  summarise(n_x1=n())

x2_count <- df %>%
  group_by(x2) %>%
  summarise(n_x2=n())

x3_count <- df %>%
  group_by(x3) %>%
  summarise(n_x3=n())

all_count <- full_join(x1_count, x2_count,
                       by=c("x1"="x2")) %>%
  full_join(., x3_count,
            by=c("x1"="x3")) %>%
  rename("x"="x1")

Есть ли какая-то работа, где мне не нужно было бы выводить несколько фреймов данных а затем объединить их. Я бы предпочел более чистое и элегантное решение.

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

простой тидир

library(tidyr)
df %>%
  pivot_longer(everything(),names_to="variables",values_to="values") %>%
  group_by(variables,values) %>%
  summarize(n_x=n()) %>%
  ungroup() %>%
  pivot_wider(names_from = variables,values_from=n_x)

# A tibble: 11 x 4
   values    x1    x2    x3
    <dbl> <int> <int> <int>
 1      0     1     7     2
 2      1     2     4     3
 3      2     2     3     3
 4      3     3     3     3
 5      4     2     1     2
 6      5     1    NA    NA
 7      6     2    NA     3
 8      7     1    NA     1
 9      8     1    NA    NA
10      9     2    NA     1
11     10     1    NA    NA
2 голосов
/ 08 мая 2020

Мы можем использовать простой map с full_join

library(dplyr)
library(purrr)
map(names(df), ~ df %>% 
           count(!!rlang::sym(.x)) %>%
           rename_at(1, ~ 'x')) %>%
     reduce(full_join, by = 'x') %>%
     rename_at(-1, ~ str_c('n_x', seq_along(.)))
#     x n_x1 n_x2 n_x3
#1   0    1    7    2
#2   1    2    4    3
#3   2    2    3    3
#4   3    3    3    3
#5   4    2    1    2
#6   5    1   NA   NA
#7   6    2   NA    3
#8   7    1   NA    1
#9   8    1   NA   NA
#10  9    2   NA    1
#11 10    1   NA   NA

Или используя простой base R вариант

t(table(c(col(df)), unlist(df)))
...