R 跨多个列匹配多个字符串,并创建一个yes/no(1/0)列

R 跨多个列匹配多个字符串,并创建一个yes/no(1/0)列,r,R,编辑以添加代码: 我试图复制一位使用SAS的同事的一些工作。SAS中的导入存在问题,它将文本(匹配布尔值)转换为数字 这项工作的目的是确定要传递的特定记录,因此我们需要将值保留为最初导入的值(我认为R可以做到这一点)。目前,我们正在手动修复该问题,因为它只有少量记录,但这可能并不总是正确的 我遇到的问题是,我需要在R中复制它们的矩阵数组。有多个条件,如果它们满足条件,应该用1标记,如下所示: 我需要能够评估12列中的一列中是否有34个潜在字符串(或部分字符串(在SAS中,冒号将比较值缩短为与评

编辑以添加代码:

我试图复制一位使用SAS的同事的一些工作。SAS中的导入存在问题,它将文本(匹配布尔值)转换为数字

这项工作的目的是确定要传递的特定记录,因此我们需要将值保留为最初导入的值(我认为R可以做到这一点)。目前,我们正在手动修复该问题,因为它只有少量记录,但这可能并不总是正确的

我遇到的问题是,我需要在R中复制它们的矩阵数组。有多个条件,如果它们满足条件,应该用1标记,如下所示:

我需要能够评估12列中的一列中是否有34个潜在字符串(或部分字符串(在SAS中,冒号将比较值缩短为与评估值相同的长度并进行比较)(例如:Q16表示字符串只需要从Q16开始)。此外,12个字段中的任何一个都可能有一个值,但在后面的字段中会变得更稀疏

如果可能的话,我正试图找到最有效、最紧凑的方法

对于更复杂的问题,我在R还是有点生疏,所以我被阻碍了。 我尝试了一些方法来处理grep和grepl,但都没有结果。 当我尝试regex时,我尝试在ifelse中单独使用每个字符串,然后我还尝试了一个带有“|”运算符的较大字符串,但也没有成功。我还尝试了base(apply)和dplyr方法

感谢您的帮助

数据结构如下:

代码示例数据:

structure(list(record = 1:20, 
icd1 = c("Q753", "Q620", "Q825", "Q211", "Q828", "Q6532", "Q673", "Q380", "Q5310", "Q040", "Q107", "Q6689", "Q860", "Q753", "Q000", "Q673", "Q860", "Q673", "H9190", "Q381"), 
icd2 = c("Q141",NA,NA, "Q170", NA, NA, NA, NA, NA, NA, NA, "Q211", NA, NA, "Q211", "Q673", NA, "115", "Q759", "Q753"), 
icd3 = c("Q579", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q038", "H4657", "Q211"), 
icd4 = c("Q656", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q999", NA, NA), 
icd5 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q5301", NA, NA), 
icd6 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q168", NA, NA), 
icd7 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd8 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd9 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd10 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd11 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd12 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), 
.Names = c("record", "icd1", "icd2", "icd3", "icd4", "icd5", "icd6", "icd7", "icd8", "icd9", "icd10", "icd11", "icd12"), 
class = "data.frame", row.names = c(NA, -20L))
利息串:

case2 <- "^H4703| ^H90*| ^H91*| ^Q000| ^Q001| ^Q002| ^Q01*| ^Q02| ^Q03*|
^Q04*| ^Q05*| ^Q070*| ^Q110| ^Q111| ^Q112| ^Q120| ^Q122| ^Q130| ^Q138|
^Q139| ^Q141| ^Q142| ^Q143| ^Q148| ^Q149| ^Q16*| ^Q65*| ^Q66*| ^Q674| 
^Q688| ^Q743| ^Q758| ^Q759| ^Q828" 

case2为此,我稍微修改了您的字符串。简言之,我将您的数据帧从宽转换为长,然后将每个列总结为具有(TRUE)或不具有(FALSE)任何您想要的字符串

case2 <- "H4703|H90|H91|Q000|Q001|Q002|Q01|Q02|Q03|Q04|Q05|Q070|Q110|Q111|Q112|Q120|Q122|Q130|Q138|Q139|Q141|Q142|Q143|Q148|Q149|Q16|Q65|Q66|Q674|Q688|Q743|Q758|Q759|Q828" 

library(dplyr)
library(tidyr)

df %>% 
  gather(column, string, -record) %>%
  group_by(column) %>%
  summarise(contains_string = sum(grepl(case2, string))>0) 
#> # A tibble: 12 x 2
#>    column contains_string
#>    <chr>  <lgl>          
#>  1 icd1   TRUE           
#>  2 icd10  FALSE          
#>  3 icd11  FALSE          
#>  4 icd12  FALSE          
#>  5 icd2   TRUE           
#>  6 icd3   TRUE           
#>  7 icd4   TRUE           
#>  8 icd5   FALSE          
#>  9 icd6   TRUE           
#> 10 icd7   FALSE          
#> 11 icd8   FALSE          
#> 12 icd9   FALSE
case2%
聚集(列,字符串,-记录)%>%
分组依据(列)%>%
摘要(包含_string=sum(grepl(case2,string))>0)
#>#tibble:12 x 2
#>列包含\u字符串
#>                
#>1 icd1正确
#>2 icd10错误
#>3 icd11错误
#>4 icd12错误
#>5 icd2正确
#>6 icd3正确
#>7 icd4正确
#>8 icd5错误
#>9 icd6正确
#>10 icd7错误
#>11 icd8错误
#>12 icd9错误
编辑

这是每行的

df %>% 
  gather(column, string, -record) %>%
  group_by(record) %>%
  mutate(contains_string = sum(grepl(case2, string))>0) %>%
  spread(column, string)
#> # A tibble: 20 x 14
#> # Groups:   record [20]
#>    record contains_string icd1  icd10 icd11 icd12 icd2  icd3  icd4  icd5 
#>     <int> <lgl>           <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#>  1      1 TRUE            Q753  <NA>  <NA>  <NA>  Q141  Q579  Q656  <NA> 
#>  2      2 FALSE           Q620  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  3      3 FALSE           Q825  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  4      4 FALSE           Q211  <NA>  <NA>  <NA>  Q170  <NA>  <NA>  <NA> 
#>  5      5 TRUE            Q828  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  6      6 TRUE            Q6532 <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  7      7 FALSE           Q673  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  8      8 FALSE           Q380  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  9      9 FALSE           Q5310 <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 10     10 TRUE            Q040  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 11     11 FALSE           Q107  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 12     12 TRUE            Q6689 <NA>  <NA>  <NA>  Q211  <NA>  <NA>  <NA> 
#> 13     13 FALSE           Q860  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 14     14 FALSE           Q753  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 15     15 TRUE            Q000  <NA>  <NA>  <NA>  Q211  <NA>  <NA>  <NA> 
#> 16     16 FALSE           Q673  <NA>  <NA>  <NA>  Q673  <NA>  <NA>  <NA> 
#> 17     17 FALSE           Q860  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 18     18 TRUE            Q673  <NA>  <NA>  <NA>  115   Q038  Q999  Q5301
#> 19     19 TRUE            H9190 <NA>  <NA>  <NA>  Q759  H4657 <NA>  <NA> 
#> 20     20 FALSE           Q381  <NA>  <NA>  <NA>  Q753  Q211  <NA>  <NA> 
#> # ... with 4 more variables: icd6 <chr>, icd7 <chr>, icd8 <chr>,
#> #   icd9 <chr>
df%>%
聚集(列,字符串,-记录)%>%
分组依据(记录)%>%
mutate(contains_string=sum(grepl(case2,string))>0)%
排列(列、字符串)
#>#A tibble:20 x 14
#>#分组:记录[20]
#>记录包含字符串icd1 icd10 icd11 icd12 icd2 icd3 icd4 icd5
#>                        
#>1 1真正的Q753 Q141 Q579 Q656
#>2错误Q620
#>3错误Q825
#>4错误Q211 Q170
#>5真正的Q828
#>6真正的Q6532
#>7错误Q673
#>8错误Q380
#>9错误Q5310
#>10 10真实Q040
#>11 11错误Q107
#>12 12真实Q6689 Q211
#>13假Q860
#>14错误Q753
#>15真实Q000 Q211
#>16 16错误Q673 Q673
#>17错误Q860
#>18 18 18真实Q673 115 Q038 Q999 Q5301
#>19 19真实H9190 Q759 H4657
#>20 20错误Q381 Q753 Q211
#>#…还有4个变量:icd6、icd7、icd8、,
#>#icd9

由(v0.2.0)于2018-09-19创建。

这里有一个与@AndS类似的方法,使用
pmatch
获得部分匹配

library(tidyverse)
my_data2 <- my_data %>%
  gather(question, value, -record) %>%
  mutate(first_match = case2[pmatch(value, case2, duplicates.ok = TRUE)])

> head(my_data2)
  record question value first_match
1      1     icd1  Q753        <NA>
2      2     icd1  Q620        <NA>
3      3     icd1  Q825        <NA>
4      4     icd1  Q211        <NA>
5      5     icd1  Q828        Q828
6      6     icd1 Q6532        <NA>
1) 在向量中定义查找字符串:

case2 <- c("H4703", "H90", "H91", "Q000", "Q001", "Q002", "Q01", "Q02", "Q03",
"Q04", "Q05", "Q070", "Q110", "Q111", "Q112", "Q120", "Q122", "Q130", "Q138",
"Q139", "Q141", "Q142", "Q143", "Q148", "Q149", "Q16", "Q65", "Q66", "Q674", 
"Q688", "Q743", "Q758", "Q759", "Q828")
3) 最后,确定哪些行至少有一个匹配项:

my_data2 %>%
  group_by(record) %>%
  summarize(contains_string = any(!is.na(first_match)))

# A tibble: 20 x 2
   record contains_string
    <int> <lgl>          
 1      1 TRUE           
 2      2 FALSE          
 3      3 FALSE          
 4      4 FALSE          
 5      5 TRUE           
 6      6 FALSE          
 7      7 FALSE          
 8      8 FALSE          
 9      9 FALSE          
10     10 FALSE          
11     11 FALSE          
12     12 FALSE          
13     13 FALSE          
14     14 FALSE          
15     15 TRUE           
16     16 FALSE          
17     17 FALSE          
18     18 FALSE          
19     19 TRUE           
20     20 FALSE
my_data 2%>%
分组依据(记录)%>%
汇总(包含字符串=任何(!is.na(第一个匹配)))
#一个tibble:20x2
记录包含\u字符串
11正确
2错误
3 3错误
4错误
5对
6错误
7错误
8错误
9错误
10错误
11错误
12错误
13错误
14错误
15对
16错误
17错误
18错误
19 19对
20错误

看起来您正在重新设计共病分配,其中有几个R包。我大约在六年前为此目的而创建,它在社区中被广泛使用。它是准确和非常快的。对于您的应用程序,我将创建一个自定义共病映射(只是一个命名列表,每个成员都是匹配代码干的向量)

库(icd)

#如果你能在一个可复制的例子中分享你的数据,人们会更容易给你一个具体的答案。你能发布目标字符串的样本吗?@JonSpringdone@AndS. 我添加了感兴趣的字符串。@pophealth将所有感兴趣的字符串写在一个向量中,即
case2=c('H4703','H90',…)
,对于那些带有冒号的字符串,例如
:Q16
将它们重写为
Q16.*
,这样您就有了
case2=c('H4703','H90','Q16.*,…)
。现在做
structure(grepl(paste0(case2,collapse='|')、as.matrix(data))、.Dim=Dim(data))
我可能是错的,但我认为OP是在测试每个记录(跨越12列)中的任何匹配,而不是每个列(ac)中的匹配
library(icd)
# x <- your_data_structure_above
examplemap <- list(
  case2 = c("H4703", "H90", "H91", "Q000", "Q001", "Q002", "Q01", "Q02", 
            "Q03", "Q04", "Q05", "Q070", "Q110", "Q111", "Q112", "Q120", 
            "Q122", "Q130", "Q138", "Q139", "Q141", "Q142", "Q143", "Q148", 
            "Q149", "Q16", "Q65", "Q66*", "Q674", "Q688", "Q743", "Q758", 
            "Q759", "Q828"))
icd::comorbid(x, examplemap)