提问人:OnlyDean 提问时间:11/15/2023 最后编辑:jpsmithOnlyDean 更新时间:11/15/2023 访问量:67
R tidyverse - 如何创建对列求和的行
R tidyverse - How to create a row summing the columns
问:
下面是我的数据示例:
GRADE_LVL | COURSE_NAME | COURSE_CODE | STUDENT_GENDER | 种族 | 结果 |
---|---|---|---|---|---|
12 | 物理 | 03165 | 雄 | 白 | 通过 |
12 | 物理 | 03165 | 女性 | 白 | 通过 |
12 | 物理 | 03165 | 非二进制 | 黑人或非裔美国人 | 通过 |
9 | 代数 I | 02052 | 女性 | 多种族 | 通过 |
10 | 代数 I | 02052 | 女性 | 白 | 失败 |
我正在尝试编写一个函数,该函数将过滤条件作为参数,然后输出一个包含所有性别/种族组合计数的 tibble,其中一列汇总所有行,一行汇总所有列。我坚持添加对所有列求和的行。
我的输出应该是什么样子的示例:
西班牙的 | 印第安人 | 亚裔 | 黑 | 白 | 多种族 | 总 | |
---|---|---|---|---|---|---|---|
雄 | 0 | 0 | 7 | 2 | 13 | 4 | 26 |
女性 | 1 | 0 | 3 | 1 | 12 | 3 | 20 |
非二进制 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
总 | 1 | 0 | 10 | 3 | 26 | 7 | 47 |
这是我的代码:
middleSchool = c('07', '08')
algebra1 <- quo(COURSE_CODE_ALT == algebra1CourseCode)
ethnicCategories <- factor(c(
'Hispanic or Latino',
'American Indian or Alaska Native',
'Asian',
'Native Hawaiian/Other Pacific Islander',
'Black or African American',
'White',
'Multiracial'
))
genderCategories <- factor(c('Female', 'Male', 'Nonbinary'))
getDemographics <- function(filterConditions, gradeLevels) {
COUR_APID_data |>
filter(
{{filterConditions}} &
CURR_GRADE_LVL %in% gradeLevels
) |>
mutate(
Gender = factor(STUDENT_GENDER, levels = genderCategories),
ethnicity = factor(ETHNIC_DESC, levels = ethnicCategories)
) |>
count(Gender, ethnicity, .drop = FALSE) |>
pivot_wider(names_from = ethnicity, values_from = n) |>
mutate(Total = rowSums(select(., -c(Gender)))) |>
add_row(summarize(
across(where(is.numeric), sum),
across(where(is.character), ~'Total')
))
}
report <- getDemographics(
filterConditions = !!quo(!!algebra1),
gradeLevels = middleSchool
)
当我运行它时,我收到以下错误:
Error in `pick()`:
! Must only be used inside data-masking verbs like `mutate()`, `filter()`, and `group_by()`.
Backtrace:
1. global getDemographics(filterConditions = !!quo(!!algebra1), gradeLevels = middleSchool)
8. dplyr::pick("Hispanic or Latino")
我已经在谷歌上搜索了很长一段时间,并尝试了我在网上看到的多种解决方案,但到目前为止,没有一个能为我成功运行。在添加“总计行”之前,代码一直有效。“总计列”有效,但据我所知只能在列上使用。mutate
答:
2赞
jpsmith
11/15/2023
#1
如果您想根据输入变量(,即,)和值(即“物理”)过滤数据,您应该能够简单地使用并创建您想要的内容,将其包装在:filtervar
COURSE_NAME
filterval
table
addmargins
as.data.frame.matrix
myfun <- function(data, filtervar, filterval){
fdata <- data %>% filter({{filtervar}} %in% filterval) %>% select(STUDENT_GENDER, ETHNICITY)
as.data.frame.matrix(addmargins(table(fdata)))
}
# with sample data
myfun(df, COURSE_NAME, "Physics")
# Black or African American White Sum
# Female 0 1 1
# Male 0 1 1
# Nonbinary 1 0 1
# Sum 1 2 3
数据:
df <- read.table(text = "GRADE_LVL COURSE_NAME COURSE_CODE STUDENT_GENDER ETHNICITY OUTCOME
12 Physics 03165 Male White Pass
12 Physics 03165 Female White Pass
12 Physics 03165 Nonbinary 'Black or African American' Pass
9 'Algebra I' 02052 Female Multiracial Pass
10 'Algebra I' 02052 Female White Fail", h = TRUE)
2赞
Mark
11/15/2023
#2
以下是从看门人包中执行此操作的方法:adorn_totals()
pacman::p_load(janitor, tidyverse)
getDemographics <- function(filterConditions, gradeLevels) {
data |>
filter(
{{filterConditions}} &
GRADE_LVL %in% gradeLevels) |>
mutate(
Gender = factor(STUDENT_GENDER, levels = genderCategories),
ethnicity = factor(ETHNIC_DESC, levels = ethnicCategories)) |>
count(Gender, ethnicity, .drop = FALSE) |>
pivot_wider(names_from = ethnicity, values_from = n, values_fill = 0) |>
adorn_totals(c("row", "col"))
}
getDemographics(
filterConditions = !!quo(COURSE_CODE == '02052'),
gradeLevels = c(09, 10)
)
输出:
Gender Hispanic or Latino American Indian or Alaska Native Asian
Female 0 0 0
Male 0 0 0
Nonbinary 0 0 0
Total 0 0 0
Native Hawaiian/Other Pacific Islander Black or African American White
0 0 1
0 0 0
0 0 0
0 0 1
Multiracial Total
1 2
0 0
0 0
1 2
评论
0赞
OnlyDean
11/16/2023
谢谢,这是我选择的解决方案。我只是感到惊讶的是,在基础 R 或 tidyverse 的某个地方已经没有更简单的解决方案。必须安装一个新包似乎很奇怪。
0赞
Mark
11/16/2023
有一些方法可以用 base R(参见 jpsmith 的答案)和 tidyverse,它只是不是一行(很少有东西!
评论