R tidyverse - 如何创建对列求和的行

R tidyverse - How to create a row summing the columns

提问人:OnlyDean 提问时间:11/15/2023 最后编辑:jpsmithOnlyDean 更新时间:11/15/2023 访问量:67

问:

下面是我的数据示例:

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

r 整洁的宇宙

评论

1赞 Mark 11/15/2023
Dean,你不需要两次quo()代数代码
1赞 Mark 11/15/2023
此外,最好将 dput() 包含在示例数据中。你已经提出了50 +问题,你现在应该知道了。JPMisk的示例 DF 在您的函数上失败,因为您已将年级级别设置为字符串,并且许多变量名称不匹配

答:

2赞 jpsmith 11/15/2023 #1

如果您想根据输入变量(,即,)和值(即“物理”)过滤数据,您应该能够简单地使用并创建您想要的内容,将其包装在:filtervarCOURSE_NAMEfiltervaltableaddmarginsas.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,它只是不是一行(很少有东西!