根据变量“以”以vector指定的字符串开头过滤行

时间:2016-11-23 19:44:24

标签: r

我正在尝试根据特定的ICD9(诊断)代码过滤患者数据库。我想使用一个向量来指示ICD9代码的前3个字符串。

示例数据库包含每个患者就诊的IC9代码的3个字符变量(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%函数,如上所示,但我无法让它适用于我的情况。我很感激您提供的任何帮助。

感恩节快乐

阿尔比特

3 个答案:

答案 0 :(得分:0)

这看起来很接近你正在寻找的东西,但需要更多的操作:

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

答案 1 :(得分:0)

您可以从兴趣向量制作正则表达式模式并将其应用于数据框的每一列(patient id除外),使用rowSums检查行匹配是否存在任何变量模式:

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

另一种选择是将Reducelapply

一起使用
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

当您有两个以上的模式且不同的模式具有不同的字符长度时,此方法有效,例如,如果dxdx<-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

检查thisthis堆栈答案,了解有关正则表达式中多个条件的更多信息。

答案 2 :(得分:0)

您可以使用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))