Создание вывода в стиле "кросс-таблицы" - PullRequest
0 голосов
/ 07 января 2020

У меня есть образец набора данных:

id <- 1:100
gender <- sample(c('M','F'), 100, replace=TRUE)
age <- sample(18:22, 100, replace=TRUE)
ethnicity <- sample(c('W','B','H','A','O'), 100, replace = TRUE)
grade <- sample(LETTERS[1:4], 100, replace=TRUE)

df <- cbind(id,gender,age,ethnicity,grade) %>% as.data.frame()

Мой вывод, который я пытаюсь достичь, таков:

+-------------+-------+----+----+----+----+
| Column Name | Value | A  | B  | C  | D  |
+-------------+-------+----+----+----+----+
| Gender      | F     | 15 | 11 | 17 | 10 |
| Gender      | M     |  9 | 17 | 14 |  7 |
| Age         | 18    |  4 |  6 |  5 |  4 |
| Age         | 19    |  3 |  6 |  4 |  3 |
| Age         | 20    |  5 |  6 |  7 |  3 |
| Age         | 21    |  7 |  7 |  5 |  4 |
| Age         | 22    |  5 |  3 | 10 |  3 |
| Ethnicity   | A     |  1 |  9 |  9 |  6 |
| Ethnicity   | B     |  7 |  8 |  5 |  2 |
| Ethnicity   | H     |  4 |  4 |  5 |  2 |
| Ethnicity   | O     |  6 |  4 |  5 |  4 |
| Ethnicity   | W     |  6 |  3 |  7 |  3 |
+-------------+-------+----+----+----+----+

Так что я не пытаясь создать строку, в которой говорится, объединяет три категориальные переменные (например: «Испанцы c Женщины в возрасте 22 лет получили 2 А, 0 В, 2 C и т.д. c ...» Я просто хочу это с разбивкой по классам по полу, возрасту и этнической принадлежности, но все они в одном столбце.

Какой лучший способ выполнить sh это?

Ответы [ 2 ]

1 голос
/ 07 января 2020

Используя dplyr и tidyr, мы можем получить данные в длинном формате, count вхождения каждого value для каждого grade и получить данные обратно в широком формате.

library(dplyr)
library(tidyr)

df %>%
 select(-id) %>%
 pivot_longer(cols = -grade) %>%
 count(value, grade) %>%
 pivot_wider(names_from = grade, values_from = n)


# A tibble: 12 x 5
#   value     A     B     C     D
#   <fct> <int> <int> <int> <int>
# 1 F         8    10    12    13
# 2 M        13    18    11    15
# 3 18        2     4     7     6
# 4 19        5     6     4     4
# 5 20        3     6     3     8
# 6 21        6     5     5     3
# 7 22        5     7     4     7
# 8 A         5     3     1     5
# 9 B         5     5     6     7
#10 H         1     4     3     3
#11 O         3    10     7     7
#12 W         7     6     6     6

данные

set.seed(123)
id <- 1:100
gender <- sample(c('M','F'), 100, replace=TRUE)
age <- sample(18:22, 100, replace=TRUE)
ethnicity <- sample(c('W','B','H','A','O'), 100, replace = TRUE)
grade <- sample(LETTERS[1:4], 100, replace=TRUE)
df <- cbind(id,gender,age,ethnicity,grade) %>% as.data.frame()
0 голосов
/ 07 января 2020

Мы можем использовать melt/dcast из data.table

library(data.table)
dcast(melt(setDT(df[, -1]), id.var = 'grade'), value ~ grade, length)
#    value  A  B  C  D
# 1:    18  2  4  7  6
# 2:    19  5  6  4  4
# 3:    20  3  6  3  8
# 4:    21  6  5  5  3
# 5:    22  5  7  4  7
# 6:     A  5  3  1  5
# 7:     B  5  5  6  7
# 8:     F  8 10 12 13
# 9:     H  1  4  3  3
#10:     M 13 18 11 15
#11:     O  3 10  7  7
#12:     W  7  6  6  6

данные

set.seed(123)
id <- 1:100
gender <- sample(c('M','F'), 100, replace=TRUE)
age <- sample(18:22, 100, replace=TRUE)
ethnicity <- sample(c('W','B','H','A','O'), 100, replace = TRUE)
grade <- sample(LETTERS[1:4], 100, replace=TRUE)
df <- data.frame(id, gender, age, ethnicity, grade)
...