Я следую очень полезному решению по созданию сводного столбца для нескольких категорий. Как обсуждалось в связанном решении, я работаю с кодом, который генерирует процентный столбец для каждой подгруппы.
Соответствующий пример кода из связанного решения:
mtcars %>%
group_by (am, gear) %>%
summarise (n=n()) %>%
mutate(rel.freq = paste0(round(100 * n/sum(n), 0), "%"))
Код генерирует нужные значения:
## Source: local data frame [4 x 4]
## Groups: am
##
## am gear n rel.freq
## 1 0 3 15 79%
## 2 0 4 4 21%
## 3 1 4 8 62%
## 4 1 5 5 38%
Проблема
Я хотел бы изменить этот код, чтобы динамически создавать столбцы, относящиеся к уникальным категориям, доступным во второй категории, переданной в вызове dplyr
. Это будет gear
в случае прикрепленного примера. Таким образом, в случае прикрепленного примера результирующий фрейм данных будет выглядеть так:
am gear n rel.freq_gear3 rel.freq_gear4 rel.freq_gear5
1 0 3 15 79% 21%
2 1 4 8 0 62% 38%
Попытки
Я предполагаю, что для небольшого числа категорий я смогу использовать суммирование значений в conditionally
, как обсуждалось здесь, где я бы попытался выполнить операторы dplyr
только для указанных условий sumBfoo = sum(B[A=="foo"]))
. Однако такой подход будет неэффективен при работе с несколькими категориями. Вне dplyr
решение можно разработать с использованием цикла и перескакивания через уникальные значения нужной категории, но я хотел бы сделать это в dplyr
.
Образец таблицы
Вообще говоря, я хотел бы создать таблицу, подобную приведенной ниже:
library(gmodels)
CrossTable(mtcars$am, mtcars$gear)
Cell Contents
|-------------------------|
| N |
| Chi-square contribution |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 32
| mtcars$gear
mtcars$am | 3 | 4 | 5 | Row Total |
-------------|-----------|-----------|-----------|-----------|
0 | 15 | 4 | 0 | 19 |
| 4.169 | 1.371 | 2.969 | |
| 0.789 | 0.211 | 0.000 | 0.594 |
| 1.000 | 0.333 | 0.000 | |
| 0.469 | 0.125 | 0.000 | |
-------------|-----------|-----------|-----------|-----------|
1 | 0 | 8 | 5 | 13 |
| 6.094 | 2.003 | 4.339 | |
| 0.000 | 0.615 | 0.385 | 0.406 |
| 0.000 | 0.667 | 1.000 | |
| 0.000 | 0.250 | 0.156 | |
-------------|-----------|-----------|-----------|-----------|
Column Total | 15 | 12 | 5 | 32 |
| 0.469 | 0.375 | 0.156 | |
-------------|-----------|-----------|-----------|-----------|
Но меня интересуют только пропорции строки без подсчета, итогов и других гаджетов.
n
.library(tidyr); count(mtcars, am, gear) %>% mutate(rel.freq = paste0(round(100 * n/sum(n), 0), "%")) %>% spread(gear, rel.freq)
- person talat   schedule 30.11.2015dplyr
. - person Konrad   schedule 30.11.2015plyr
, который я только что нашел. - person Konrad   schedule 30.11.2015n
в вашем ожидаемом выводе кажется неправильным. Вам также не хватает 0 (или NA) в первой строке, в последнем столбце. - person Axeman   schedule 30.11.2015