在R中基于向量中指定的列表的子集数据框(使用 "start with "表达式或等价物)。

问题描述 投票:0回答:1

我试图在一个超过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万行,并基于此子集。

r dataframe subset startswith
1个回答
1
投票

这是一个使用 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
© www.soinside.com 2019 - 2024. All rights reserved.