[英]Looping over columns with mutate and case_when
我想遍歷許多列並在某些條件下替換值。 例如,如果 disease=0 且treatment=1,則將處理單元替換為 99。
數據:
df <- data.frame(id=1:5,
disease1=c(1,1,0,0,0),
treatment1=c(1,0,1,0,0),
outcome1=c("survived", "died", "survived", NA,NA),
disease2=c(1,1,0,0,0),
treatment2=c(1,0,1,0,0),
outcome2=c("survived", "died", "survived", NA,NA))
> df
id disease1 treatment1 outcome1 disease2 treatment2 outcome2
1 1 1 1 survived 1 1 survived
2 2 1 0 died 1 0 died
3 3 0 1 survived 0 1 survived
4 4 0 0 <NA> 0 0 <NA>
5 5 0 0 <NA> 0 0 <NA>
對於單個列, case_when 效果很好:
df %>% mutate(treatment=case_when((disease1!=1&treatment1==1)~99, TRUE~treatment1))
對於多列,以下在基礎 R 中有效:
for(i in 1:2) {
df[,paste0("treatment",i)] <- ifelse(df[,paste0("disease",i)]!=1&df[,paste0("treatment",i)]==1,99, df[,paste0("treatment",i)])
}
我正在尋找一種在 tidyverse 中完成這一切的方法,但我很難找到正確的食譜。 先感謝您。
也許考慮使用pivot_longer
輸入長格式,然后在多個列之間進行mutate
會更容易。 如果所有疾病都應放在一個列中(並且對於 1 列中的治療和 1 列中的結果相同),這將是一種“更整潔”的方法。
library(tidyverse)
df %>%
pivot_longer(cols = -id, names_to = c(".value", "number"), names_pattern = "(\\w+)(\\d+)") %>%
mutate(treatment = ifelse(disease == 0 & treatment == 1, 99, treatment))
帶有names_sep
的pivot_longer
中的case_when
選項
library(dplyr)
library(tidyr)
pivot_longer(df, cols = -id, names_to = c('.value', 'number'),
names_sep="(?<=[a-z])(?=[0-9])") %>%
mutate(treatment = replace(treatment, !disease & treatment == 1, 99))
# A tibble: 10 x 5
# id number disease treatment outcome
# <int> <chr> <dbl> <dbl> <chr>
# 1 1 1 1 1 survived
# 2 1 2 1 1 survived
# 3 2 1 1 0 died
# 4 2 2 1 0 died
# 5 3 1 0 99 survived
# 6 3 2 0 99 survived
# 7 4 1 0 0 <NA>
# 8 4 2 0 0 <NA>
# 9 5 1 0 0 <NA>
#10 5 2 0 0 <NA>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.