我正在尝试根据特定的ICD9(诊断)代码过滤患者数据库。我想使用指示ICD9代码的前3个字符串的向量。
示例数据库包含3个字符变量,用于每次患者访问的IC9代码(VAR1至VAR3)。
以下是数据的示例
patient<-c("a","b","c")
var1<-c("8661", "865","8651")
var2<-c("8651","8674","2866")
var3<-c("2430","3456","9089")
observations<-data_frame(patient,var1,var2,var3)
patient var1 var2 var3
1 a 8661 8651 2430
2 b 865 8674 3456
3 c 8651 2866 9089
#diagnosis of interest: all beginning with "866" and "867"
dx<-c("866","867")
filtered_data<- filter(observations, var1 %like% dx | var2 %like% dx | var3 %like% dx)
我已经尝试了几种方法,包括GREP和%like%函数,如上所述,但我无法使其适合我的情况。感谢您提供的任何帮助。
感恩节快乐
albit
您可以从兴趣向量中制作一个正则表格模式,并将其应用于数据框的每一列,除了patient
ID,请使用rowSums
检查行中是否有任何var匹配模式:
library(dplyr)
pattern = paste("^(", paste0(dx, collapse = "|"), ")", sep = "")
pattern
# [1] "^(866|867)"
filter(observations, rowSums(sapply(observations[-1], grepl, pattern = pattern)) != 0)
# A tibble: 2 × 4
# patient var1 var2 var3
# <chr> <chr> <chr> <chr>
#1 a 8661 8651 2430
#2 b 865 8674 3456
另一个选择是将Reduce
与lapply
:
filter(observations, Reduce("|", lapply(observations[-1], grepl, pattern = pattern)))
# A tibble: 2 × 4
# patient var1 var2 var3
# <chr> <chr> <chr> <chr>
#1 a 8661 8651 2430
#2 b 865 8674 3456
当您拥有更多的两个模式和不同模式的字符长度时,此方法有效,例如,如果您的dx
为dx<-c("866","867", "9089")
:
dx<-c("866","867", "9089")
pattern = paste("^(", paste0(dx, collapse = "|"), ")", sep = "")
pattern
# [1] "^(866|867|9089)"
filter(observations, Reduce("|", lapply(observations[-1], grepl, pattern = pattern)))
# A tibble: 3 × 4
# patient var1 var2 var3
# <chr> <chr> <chr> <chr>
#1 a 8661 8651 2430
#2 b 865 8674 3456
#3 c 8651 2866 9089
检查此问题,此堆栈答案以获取更多有关REGEX中的多个或条件。
这看起来很接近您想要的东西,但需要更多的操作:
library(dplyr)
library(stringr)
library(tidyr)
obs2 <- observations %>%
gather(vars, value, -patient) %>%
filter(str_sub(value, 1, 3) %in% dx)
# A tibble: 2 × 3
patient vars value
<chr> <chr> <chr>
1 a var1 8661
2 b var2 8674
您可以使用apply和ldply
library(plyr)
filtered_obs <- apply(observations, 1, function(x) if(sum(substr(x,1,3) %in% dx)>0){x})
filtered_obs <- plyr::ldply(filtered_obs,rbind)
如果您的字符数量可变,则应该有效 -
filtered_obs <- lapply(dx, function(y)
{
plyr::ldply(apply(observations, 1, function(x)
{
if(sum(substr(x,1,nchar(y)) %in% y)>0){x}
}), rbind)
})
filtered_obs <- unique(plyr::ldply(filtered_obs,rbind))