在多个多列中匹配多个字符串,并创建一个是/否(1/0)列

时间:2018-09-19 19:40:13

标签: r

编辑后添加代码:

我正在尝试复制使用SAS的同事的一些工作。 SAS中的导入将文本(与布尔值匹配)转换为数字时遇到问题。

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

我遇到麻烦的地方是我需要在R中复制它们的矩阵数组。如果满足条件,则应将多个条件标记为1,如下所示: SAS Code

我需要能够评估12列中的一列中是否存在34个潜在字符串之一(或部分字符串(在SAS中,冒号将比较值缩短为与评估值相同的长度并进行比较))例如::Q16表示字符串只需要以Q16开头。此外,这12个字符串中的任何一个都可以通过其值获得稀疏。

我正在尝试找到最有效,最紧凑的方法。

对于更复杂的问题,我仍然在R处有些陌生,所以我受阻了。 我已经尝试了使用grep和grepl的几种方法,但是都没有取得任何成果。 当我尝试使用正则表达式时,我尝试在ifelse中分别使用每个字符串,然后还尝试了一个较大的字符串,并带有“ |”操作员,但也没有运气。我还尝试了基本(应用)和dplyr方法。

感谢您的帮助。

数据的结构为: Example Table

示例数据代码:

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" 

3 个答案:

答案 0 :(得分:1)

为此,我对您的字符串做了一些修改。简而言之,我将您的数据框从宽转换为长,然后将每一列总结为具有(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

编辑

这里是每一行。

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>

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

答案 1 :(得分:0)

这与@AndS类似,使用pmatch获得部分匹配。

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")

2)延长数据长度,并使用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>

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

答案 2 :(得分:0)

您似乎正在重新发明合并症分配,为此,有几个R药盒。为此,我大约在六年前创建了icd,并且在社区中得到了广泛的使用。它是准确且非常快速的。对于您的应用程序,我将创建一个自定义合并症贴图(只是一个命名列表,每个成员都是匹配代码词干的向量)。

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)