假设我想根据多个其他变量中的条件创建一个新变量,并且每个变量的条件都是相同的。我知道我可以使用 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 )\nRun 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\nRun Code Online (Sandbox Code Playgroud)\n现在,就本示例而言,假设您有 100 个学生获得成绩的考试类别(例如,期中考试、期末考试、家庭作业等),并且您希望为每个考试类别创建一个新变量,指示是否或他们从来没有取得过不及格的成绩。人们可以迭代地检查每个考试类别,就像我上面使用 case_when() 进行考试和测验所做的那样,但我想知道是否有一种更简单的方法来将单个条件(即,如果数字分数 <70)应用于考试类别列表(例如:c(“考试”、“测验”、“家庭作业”、“期中考试”),遵循上面的编号约定,以便为以下内容创建唯一的输出变量,例如“fail_exam”和“fail_quiz”他们每一个人。
\n这不是关键任务,而是希望简化一些事情。
\n谢谢,\nC
\n您可以使用dplyr::if_any()谓词函数测试多个变量:
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 )\nRun 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\nRun Code Online (Sandbox Code Playgroud)\nPS-也看到了dplyr::if_all()。
编辑: \n在任意数量的“测验”/“考试”类别中执行相同操作的解决方案。这将按 ID 和类型创建一个单独的故障汇总表,然后您可以将其合并回原始数据帧。
\nlibrary(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)\nRun Code Online (Sandbox Code Playgroud)\n