Сокращение уровней переменной фактора в одном столбце при суммировании значений в другом
Первоначально у меня были данные различной ширины (4 строки с 158 столбцами), которые я использовал reshape::melt()
для создания длинного набора данных (624 строки х 3 столбца).
Теперь, однако, у меня есть такой набор данных:
demo <- data.frame(region = as.factor(c("North", "South", "East", "West")),
criteria = as.factor(c("Writing_1_a", "Writing_2_a", "Writing_3_a", "Writing_4_a",
"Writing_1_b", "Writing_2_b", "Writing_3_b", "Writing_4_b")),
counts = as.integer(c(18, 27, 99, 42, 36, 144, 99, 9)))
Который производит таблицу, аналогичную приведенной ниже:
region criteria counts
North Writing_1_a 18
South Writing_2_a 27
East Writing_3_a 99
West Writing_4_a 42
North Writing_1_b 36
South Writing_2_b 144
East Writing_3_b 99
West Writing_4_b 9
Теперь я хочу создать что-то вроде этого:
goal <- data.frame(region = as.factor(c("North", "South", "East", "West")),
criteria = as.factor(c("Writing_1", "Writing_2", "Writing_3", "Writing_4")),
counts = as.integer(c(54, 171, 198, 51)))
Это означает, что когда я сворачиваю столбцы критериев, он суммирует значения:
region criteria counts
North Writing_1 54
South Writing_2 171
East Writing_3 198
West Writing_4 51
Я пытался использовать forcats::fct_collapse
а также forcats::recode()
но безрезультатно - я уверен, что просто делаю это неправильно. Заранее благодарю за любую помощь, которую вы можете оказать.
2 ответа
Вы можете подумать о том, что именно вы пытаетесь сделать, чтобы изменить уровни факторов.fct_collapse
будет вручную свернуть несколько уровней в один уровень, и fct_recode
будет вручную изменять метки отдельных уровней. То, что вы пытаетесь сделать, это изменить все метки на основе применения какой-либо функции, в этом случае fct_relabel
является целесообразным.
Вы можете написать анонимную функцию при вызове fct_relabel
или просто передайте ему имя функции и аргумент (ы) этой функции. В этом случае вы можете использовать stringr::str_remove
найти и удалить шаблон регулярного выражения и регулярное выражение, такое как _[a-z]$
удалить любое подчеркивание, а затем строчные буквы, которые появляются в конце строки. Таким образом, он должен хорошо масштабироваться с вашими реальными данными, но вы можете изменить его, если нет.
library(tidyverse)
...
new_crits <- demo %>%
mutate(crit_no_digits = fct_relabel(criteria, str_remove, "_[a-z]$"))
new_crits
#> region criteria counts crit_no_digits
#> 1 North Writing_1_a 18 Writing_1
#> 2 South Writing_2_a 27 Writing_2
#> 3 East Writing_3_a 99 Writing_3
#> 4 West Writing_4_a 42 Writing_4
#> 5 North Writing_1_b 36 Writing_1
#> 6 South Writing_2_b 144 Writing_2
#> 7 East Writing_3_b 99 Writing_3
#> 8 West Writing_4_b 9 Writing_4
Проверка того, что эта новая переменная имеет только те уровни, которые вы хотите:
levels(new_crits$crit_no_digits)
#> [1] "Writing_1" "Writing_2" "Writing_3" "Writing_4"
И затем подведение итогов на основе этого нового фактора:
new_crits %>%
group_by(crit_no_digits) %>%
summarise(counts = sum(counts))
#> # A tibble: 4 x 2
#> crit_no_digits counts
#> <fct> <int>
#> 1 Writing_1 54
#> 2 Writing_2 171
#> 3 Writing_3 198
#> 4 Writing_4 51
Создано 2018-11-04 пакетом представлением (v0.2.1)
Решение dplyr с использованием регулярных выражений:
demo %>%
mutate(criteria = gsub("(_a)|(_b)", "", criteria)) %>%
group_by(region, criteria) %>%
summarize(counts = sum(counts)) %>%
arrange(criteria) %>%
as.data.frame
region criteria counts
1 North Writing_1 54
2 South Writing_2 171
3 East Writing_3 198
4 West Writing_4 51