[英]Mutate across columns case_when to make a new "Flag" column
我有一個巨大的數據集 (df),其中包含許多列,列出了每個國家 (ISO3) 和每年 (Year) 接受治療的人數 x (例如 Treat_1) 的信息。
我需要生成一個名為“Flag_Treat_X”的新列(其中 X 代表原始列名,例如 Treat_1)。 在本專欄中,我需要將與上一年相比的任何治療下降記錄為“下降”,增加為“上升”,在缺失數據的情況下記錄為 NA。 所有包含治療信息的列的名稱中都有“_”,但實際的 df 使用復雜的名稱,如 HIV_treatment 等,而不是此處使用的字符串和數字的組合。 我知道有幾種方法可以逐列(見下文),但數據集非常龐大,變量名稱經常變化,我需要一種自動化的方法來做到這一點。
這是一個簡化示例的代碼:
ISO3 <- c("AFG", "AFG","AFG", "BEN", "BEN","BEN", "GIN", "GIN", "GIN", "ZWE", "ZWE", "ZWE")
Year <- c(2020, 2021, 2022, 2020, 2021, 2022, 2020, 2021, 2022, 2020, 2021, 2022)
Treat_1 <- c(100, 110, 120, 300, 330, 360, 200, 220, 100, 300, NA, 320)
df = data.frame(ISO3, Year, Treat_1)
這是我如何逐列手動完成的示例
df_poutcome %>%
group_by(ISO3) %>%
mutate(Target_art_n_pf = case_when(Treat_1<lag(Treat_1) ~ "down",
Treat_1>lag(Treat_1) ~ "up",
TRUE ~ as.character(NA)))
這是一個使用循環“幾乎”工作的示例(不是很優雅)
for (i in grep("_", names(temp), value=TRUE)){
varname = ((gsub(" ", "", paste("Flag_",i))))
temp = temp %>%
group_by(ISO3) %>%
mutate(!!varname:= case_when(i<lag(i) ~ "down",
i>lag(i) ~ "up"))
}
錯誤是我只獲得所有新“Flag_ [...]”變量和代碼的 NA 值
TRUE ~ as.character(NA)
不在 case_when 代碼中運行,因此我必須將其刪除。
期望的結果應如下所示:
ISO3 | 年 | 款待_1 | Flag_Treat_1 |
---|---|---|---|
AFG | 2020 | 100 | 不適用 |
AFG | 2021 | 110 | 向上 |
AFG | 2022 | 120 | 向上 |
本 | 2020 | 300 | 不適用 |
本 | 2021 | 330 | 向上 |
本 | 2022 | 360 | 向上 |
杜松子酒 | 2020 | 200 | 不適用 |
杜松子酒 | 2021 | 220 | 向上 |
杜松子酒 | 2022 | 100 | 下 |
ZWE | 2020 | 300 | 不適用 |
ZWE | 2021 | 不適用 | 不適用 |
ZWE | 2022 | 320 | 不適用 |
作為獎勵,任何人都知道,自動為每種處理生成國家特定的圖以進行目視檢查會很棒。 這不那么緊急。 到目前為止,我有:
countries <- unique(df$ISO3)
plot_list <- list()
i <- 1
for (c in countries){
pl <- ggplot(data = df %>% filter(ISO3 == c)) +
geom_point(aes(Year, Treat_1), size = 3, color = 'red') +
labs(title = as.character(c), x = 'wave', y = 'value') +
theme_bw(base_size = 16) +
xlim(2020, 2022)
plot_list[[i]] <- pl
i <- i + 1
}
pdf('path/filename.pdf')
pdf.options(width = 9, height = 7)
for (i in 1:length(plot_list)){
print(plot_list[[i]])
}
dev.off()
這是針對一個治療變量 Treat_1 並且以自動方式對所有治療變量執行此操作會很棒
提前感謝您的幫助。
您可以使用 cross across()
跨具有條件的列(此處為名稱中包含"_"
的列)應用 function,並使用.names
參數命名結果列:
df %>%
group_by(ISO3) %>%
mutate(across(contains("_"),
\(x) case_when(
x < lag(x) ~ "down",
x > lag(x) ~ "up",
TRUE ~ as.character(NA)
),
.names = "flag_{.col}"
))
# # A tibble: 12 × 4
# # Groups: ISO3 [4]
# ISO3 Year Treat_1 flag_Treat_1
# <chr> <dbl> <dbl> <chr>
# 1 AFG 2020 100 NA
# 2 AFG 2021 110 up
# 3 AFG 2022 120 up
# 4 BEN 2020 300 NA
# 5 BEN 2021 330 up
# 6 BEN 2022 360 up
# 7 GIN 2020 200 NA
# 8 GIN 2021 220 up
# 9 GIN 2022 100 down
# 10 ZWE 2020 300 NA
# 11 ZWE 2021 NA NA
# 12 ZWE 2022 320 NA
非常感謝大家的快速回復。 我最終使用了混合的響應來讓它在我身邊運行。 代碼如下。
df %>%
group_by(ISO3) %>%
mutate(across(contains("_"),
~case_when(
.x < lag(.x) ~ "down",
.x > lag(.x) ~ "up",
TRUE ~ as.character(NA)
),
.names = "flag_{.col}"
))
我不得不將 Gregor Thomas 建議的\(x)
更改為 jdobres ~case_when(.x < lag(.x) ~ "down", .x > lag(.x) ~ "up", TRUE ~ as.character(NA) )
因為它給了我一個意想不到的符號
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.