我正在处理一个大型数据框,其中每一行都是一名研究参与者,其中 20 列是他们开出的药物的代码。这是一个示例,但在我的数据中,每行最多可以填充 20 个 ATC_code 列。
dset <- data.frame("studynr" = c(1:10),
"ATC_code1" = c("B05XA02", "L01XC07", "B01AC05", "B01AE07", "C02AB01",
"C03BA10", "C03BA11", " J01CF05", "R03DA11", "R06AE07"),
"ATC_code2" = c("V03AE07", "N06AB04", "N06AB10", "N06BX18", "H02AB09",
"G04CB01", "C10AA01", "C08DA01", "C07AA07", "B01AA03"))
studynr ATC_code1 ATC_code2
1 1 B05XA02 V03AE07
2 2 L01XC07 N06AB04
3 3 B01AC05 N06AB10
4 4 B01AE07 N06BX18
5 5 C02AB01 H02AB09
6 6 C03BA10 G04CB01
7 7 C03BA11 C10AA01
8 8 J01CF05 C08DA01
9 9 R03DA11 C07AA07
10 10 R06AE07 B01AA03
我有一大堆药物要从我的分析中排除,因此用 NA 替换它们在数据中的所有出现。在某些情况下,我想排除整个药物类别(因此一些排除代码只是完整药物代码的开始)。 这是一个小例子(我的排除列表大约有 500 个代码):
exclude <- c("^C03", "^B05XA02", "^C07A", "^J")
如何一次性用 NA 替换所有 20 个 ATC 列中所有出现的排除代码?
我尝试了几种不同的方法来让它工作。这是我最近的尝试,似乎已经产生了数以万计的小问题……
exclude_fx <- function(x) replace_with_na(dset, replace = list(. = exclude))
dset <- apply(dset, 1, exclude_fx)
由于您的
exclude
向量已经包含字符串开头的正则表达式 (^
),您可以折叠整个向量以使用 |
分隔各个字符串,这样我们就可以使用 grepl
检查字符串你的专栏。
将操作包装在
across(starts_with("ATC"))
中以作用于列名以“ATC”开头的所有列。然后一个简单的ifelse
将NA
分配给匹配exclude
的值。
library(dplyr)
dset %>%
mutate(across(starts_with("ATC"),
~ifelse(grepl(paste(exclude, collapse = "|"), trimws(.x)), NA, trimws(.x))))
studynr ATC_code1 ATC_code2
1 1 <NA> V03AE07
2 2 L01XC07 N06AB04
3 3 B01AC05 N06AB10
4 4 B01AE07 N06BX18
5 5 C02AB01 H02AB09
6 6 <NA> G04CB01
7 7 <NA> C10AA01
8 8 <NA> C08DA01
9 9 R03DA11 <NA>
10 10 R06AE07 B01AA03
因为你的一些字符串有前导空格,我用
trimws
在匹配字符串时删除它们。
清洗多个NA值的功能
https://github.com/tidyverse/dplyr/issues/1972
na_codes <- function(x, ...) {
x[x %in% c(...)] <- NA
x