在一列中折叠因子变量的水平,同时在另一列中求和计数
Collapsing Levels of a Factor Variable in one column while summing the counts in another
我最初有一个不同宽度的数据(4 行 158 列),我使用 reshape::melt()
创建了一个长数据集(624 行 x 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)))
这会产生一个 table 类似于下面的结果:
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()
但无济于事 - 我很肯定我只是没有做对。预先感谢您提供的任何帮助。
使用正则表达式的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
您可以想一想您究竟要尝试做什么来更改因子级别——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
由 reprex package (v0.2.1)
创建于 2018-11-04
我最初有一个不同宽度的数据(4 行 158 列),我使用 reshape::melt()
创建了一个长数据集(624 行 x 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)))
这会产生一个 table 类似于下面的结果:
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()
但无济于事 - 我很肯定我只是没有做对。预先感谢您提供的任何帮助。
使用正则表达式的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
您可以想一想您究竟要尝试做什么来更改因子级别——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
由 reprex package (v0.2.1)
创建于 2018-11-04