当多个变量的条件相同时简化 case_when()

Cas*_*sey 3 r tidyverse

假设我想根据多个其他变量中的条件创建一个新变量,并且每个变量的条件都是相同的。我知道我可以使用 case_when(),但我很好奇如果每个条件变量的条件短语都相同,是否可以简化此操作。我还想知道这是否可以轻松复制以创建多个变量。

\n

示例:教师有 3 名学生,他们获得了 3 次测试和 3 次测验的成绩。他想要创建一个变量来表示学生是否在任何测试或测验中得分低于 70。所以他将创建两个新变量,如下所示:

\n
\nID <- c("Dave", "Joe", "Steve")\nexam1 <- c(80, 100, 90)\nexam2 <- c(30, 90, 88)\nexam3 <- c(90, 65, 95)\nquiz1 <- c(90, 90, 20)\nquiz2 <- c(33, 100, 100)\nquiz3 <- c(90, 90, 50)\n\ndata <- tibble(ID, exam1, exam2, exam3, quiz1, quiz2, quiz3)\n\ndata <- data %>% \n  mutate(\n    fail_exam = case_when(\n      exam1 < 70 ~ 1,\n      exam2 < 70 ~ 1,\n      exam3 < 70 ~ 1,\n      T ~ 0\n    ),\n    fail_quiz = case_when(\n      quiz1 < 70 ~ 1,\n      quiz2 < 70 ~ 1,\n      quiz3 < 70 ~ 1,\n      T ~ 0\n    )\n  )\n
Run Code Online (Sandbox Code Playgroud)\n

他最终得到以下带有两个新变量的输出:

\n
# A tibble: 3 \xc3\x97 9\n  ID    exam1 exam2 exam3 quiz1 quiz2 quiz3 fail_exam fail_quiz\n  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>     <dbl>     <dbl>\n1 Dave     80    30    90    90    33    90         1         1\n2 Joe     100    90    65    90   100    90         1         0\n3 Steve    90    88    95    20   100    50         0         1\n
Run Code Online (Sandbox Code Playgroud)\n

现在,就本示例而言,假设您有 100 个学生获得成绩的考试类别(例如,期中考试、期末考试、家庭作业等),并且您希望为每个考试类别创建一个新变量,指示是否或他们从来没有取得过不及格的成绩。人们可以迭代地检查每个考试类别,就像我上面使用 case_when() 进行考试和测验所做的那样,但我想知道是否有一种更简单的方法来将单个条件(即,如果数字分数 <70)应用于考试类别列表(例如:c(“考试”、“测验”、“家庭作业”、“期中考试”),遵循上面的编号约定,以便为以下内容创建唯一的输出变量,例如“fail_exam”和“fail_quiz”他们每一个人。

\n

这不是关键任务,而是希望简化一些事情。

\n

谢谢,\nC

\n

zep*_*ryl 5

您可以使用dplyr::if_any()谓词函数测试多个变量:

\n
library(dplyr)\n\ndata %>% \n  mutate(\n    fail_exam = as.numeric(if_any(exam1:exam3, ~ .x < 70)),\n    fail_quiz = as.numeric(if_any(quiz1:quiz3, ~ .x < 70))\n  )\n
Run Code Online (Sandbox Code Playgroud)\n
# A tibble: 3 \xc3\x97 9\n  ID    exam1 exam2 exam3 quiz1 quiz2 quiz3 fail_exam fail_quiz\n  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>     <dbl>     <dbl>\n1 Dave     80    30    90    90    33    90         1         1\n2 Joe     100    90    65    90   100    90         1         0\n3 Steve    90    88    95    20   100    50         0         1\n
Run Code Online (Sandbox Code Playgroud)\n

PS-也看到了dplyr::if_all()

\n

编辑: \n在任意数量的“测验”/“考试”类别中执行相同操作的解决方案。这将按 ID 和类型创建一个单独的故障汇总表,然后您可以将其合并回原始数据帧。

\n
library(dplyr)\nlibrary(tidyr)\n\nfailures <- data %>% \n  pivot_longer(\n    !ID, \n    names_to = c("type", "number"),\n    names_pattern = "^(\\\\w+)(\\\\d+)$"\n  ) %>% \n  group_by(ID, type) %>%\n  summarize(\n    fail = as.numeric(any(value < 70)),\n    .groups = "drop"\n  ) %>%\n  ungroup() %>%\n  pivot_wider(\n    names_from = type,\n    names_glue = "fail_{type}",\n    values_from = fail\n  )\n\ndata %>% \n  left_join(failures)\n
Run Code Online (Sandbox Code Playgroud)\n