假設我想根據多個其他變數中的條件創建一個新變數,并且每個變數的條件都是相同的。我知道我可以使用 case_when(),但我很想知道如果我的條件短語對于每個條件變數都相同,是否可以簡化它。我還想知道這是否可以輕松復制以創建多個變數。
示例:一位教師有 3 名學生獲得了 3 次測驗和 3 次測驗的成績。他想創建一個變數來說明學生在任何測驗或測驗中的得分是否低于 70。因此,他將創建兩個新變數,如下所示:
ID <- c("Dave", "Joe", "Steve")
exam1 <- c(80, 100, 90)
exam2 <- c(30, 90, 88)
exam3 <- c(90, 65, 95)
quiz1 <- c(90, 90, 20)
quiz2 <- c(33, 100, 100)
quiz3 <- c(90, 90, 50)
data <- tibble(ID, exam1, exam2, exam3, quiz1, quiz2, quiz3)
data <- data %>%
mutate(
fail_exam = case_when(
exam1 < 70 ~ 1,
exam2 < 70 ~ 1,
exam3 < 70 ~ 1,
T ~ 0
),
fail_quiz = case_when(
quiz1 < 70 ~ 1,
quiz2 < 70 ~ 1,
quiz3 < 70 ~ 1,
T ~ 0
)
)
他的兩個新變數最終得到以下輸出:
# A tibble: 3 × 9
ID exam1 exam2 exam3 quiz1 quiz2 quiz3 fail_exam fail_quiz
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Dave 80 30 90 90 33 90 1 1
2 Joe 100 90 65 90 100 90 1 0
3 Steve 90 88 95 20 100 50 0 1
現在,為了這個示例,假設您有 100 個考試類別(例如,期中考試、期末考試、家庭作業等),學生獲得了成績,并且您希望為每個考試類別創建一個新變數,指示是否或他們從來沒有在這上面有過不及格的分數。可以像上面使用 case_when() 進行考試和測驗一樣迭代地遍歷每個考試類別,但我想知道是否有一種更簡單的方法可以將單個條件(即,如果數字分數 <70)應用于遵循我上面的編號約定的考試類別串列(例如:c("exam", "quiz", "homework", "midterm"),以便創建唯一的輸出變數,例如“fail_exam”和“fail_quiz”他們每個人。
這不是關鍵任務,但希望稍微簡化一下。
謝謝,C
uj5u.com熱心網友回復:
您可以使用dplyr::if_any()
謂詞函式測驗多個變數:
library(dplyr)
data %>%
mutate(
fail_exam = as.numeric(if_any(exam1:exam3, ~ .x < 70)),
fail_quiz = as.numeric(if_any(quiz1:quiz3, ~ .x < 70))
)
# A tibble: 3 × 9
ID exam1 exam2 exam3 quiz1 quiz2 quiz3 fail_exam fail_quiz
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Dave 80 30 90 90 33 90 1 1
2 Joe 100 90 65 90 100 90 1 0
3 Steve 90 88 95 20 100 50 0 1
PS-另見dplyr::if_all()
。
編輯: 在任意數量的“測驗”/“考試”類別中執行相同操作的解決方案。這會按 ID 和型別創建一個單獨的故障匯總表,然后您可以將其合并回原始資料框。
library(dplyr)
library(tidyr)
failures <- data %>%
pivot_longer(
!ID,
names_to = c("type", "number"),
names_pattern = "^(\\w )(\\d )$"
) %>%
group_by(ID, type) %>%
summarize(
fail = as.numeric(any(value < 70)),
.groups = "drop"
) %>%
ungroup() %>%
pivot_wider(
names_from = type,
names_glue = "fail_{type}",
values_from = fail
)
data %>%
left_join(failures)
uj5u.com熱心網友回復:
這是使用map_dfc
and的通用方式if_any
。
library(dplyr)
cols <- c("exam", "quiz")
data %>%
mutate(map_dfc(cols, ~ transmute(data, "fail_{.x}" := if_any(starts_with(.x), `<`, 70))))
輸出
# A tibble: 3 × 9
ID exam1 exam2 exam3 quiz1 quiz2 quiz3 fail_exam fail_quiz
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int>
1 Dave 80 30 90 90 33 90 1 1
2 Joe 100 90 65 90 100 90 1 0
3 Steve 90 88 95 20 100 50 0 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/527008.html
標籤:rtidyverse
上一篇:RDplyr匯總行,除非只有NA
下一篇:我想總結類似國家的銷售額