我试图在一个超过100万行的数据集中识别任何服用他汀类药物的参与者,并在此基础上进行子集。我有一个向量,其中包括这些药物的所有代码(我只是为了演示而编造了一些),接下来我想创建一个函数,通过数据框架进行搜索,并识别任何有药物代码的案例,这些代码 "以 "df中列出的任何字符开头。df看起来像这样。
ID readcode_1 readcode_2 generic_name
1 1001 bxd1 1146785342 Simvastatin
2 1002 <NA> <NA> <NA>
3 1003 <NA> <NA> Pravastatin
4 1004 <NA> <NA> <NA>
5 1005 bxd4 45432344 <NA>
6 1006 <NA> <NA> <NA>
7 1007 <NA> <NA> <NA>
8 1008 <NA> <NA> <NA>
9 1009 <NA> <NA> <NA>
10 1010 bxde <NA> <NA>
11 1011 <NA> <NA> <NA>
理想情况下,我希望最终的产品是这样的。
ID readcode_1 readcode_2 generic_name
1 1001 bxd1 1146785342 Simvastatin
3 1003 <NA> <NA> Pravastatin
5 1005 bxd4 45432344 <NA>
10 1010 bxde <NA> <NA>
这是我目前的代码(目前还不能用)。
#create vector with list of medication codes of interest
medications <- c("bxd", "Simvastatin", "1146785342", "45432344", "Pravastatin")
# look through all columns (apart from IDs in first column) and if any of them start with the codes listed in the medications vector, return a 1
df$statin_prescribed <- apply(df[, -1], 1, function(x) {
if(any(x %in% startsWith(x, medications))) {
return(1)
} else {
return(0)
}
})
# subset to include only individuals prescribed statins
df <- subset(df, statin_prescribed == 1)
似乎不工作的部分是 startsWith(x, statin)
.
请让我知道,如果你有任何建议和额外的,是否有替代的代码,可能是更有效的时间!我试图识别任何参与者服用他汀类药物的数据集超过100万行,并基于此子集。
这是一个使用 dplyr
包裹
library(dplyr)
df %>%
filter_at(vars(-ID), any_vars(grepl(paste(medications, collapse = "|"), .)))
小编解释:我们是要求 filter
所有这些行中至少有一个变量(不包括 ID
)的值开始于 medications
产量
# ID readcode_1 readcode_2 generic_name
# 1 1001 bxd1 1146785342 Simvastatin
# 2 1003 <NA> <NA> Pravastatin
# 3 1005 bxd4 45432344 <NA>
# 4 1010 bxde <NA> <NA>
另一个原理类似的基数R中的解决方案如下
df[apply(df[,-1], 1, function(x) {any(grepl(paste(medications, collapse = "|"), x))}),]
Output is the same (except row index which I believe is not relevant)
# ID readcode_1 readcode_2 generic_name
# 1 1001 bxd1 1146785342 Simvastatin
# 3 1003 <NA> <NA> Pravastatin
# 5 1005 bxd4 45432344 <NA>
# 10 1010 bxde <NA> <NA>
经过一些基准测试,基础R解决方案似乎比 dplyr
一。所以我建议你如果主要考虑时间效率的话,还是使用基础R方案。
microbenchmark::microbenchmark(
df %>% filter_at(vars(-ID), any_vars(grepl(paste(medications, collapse = "|"), .))),
df[apply(df[,-1], 1, function(x) {any(grepl(paste(medications, collapse = "|"), x))}),],
times = 100
)
# Unit: microseconds
# # expr min
# df %>% filter_at(vars(-ID), any_vars(grepl(paste(medications, collapse = "|"), .))) 1958.4
# df[apply(df[, -1], 1, function(x) { any(grepl(paste(medications, collapse = "|"), x)) }), ] 341.7
# lq mean median uq max neval
# 1989.55 2146.993 2041.30 2149.05 7851.1 100
# 352.50 405.972 380.25 401.55 2154.0 100