R 跨多个列匹配多个字符串,并创建一个yes/no(1/0)列
编辑以添加代码: 我试图复制一位使用SAS的同事的一些工作。SAS中的导入存在问题,它将文本(匹配布尔值)转换为数字 这项工作的目的是确定要传递的特定记录,因此我们需要将值保留为最初导入的值(我认为R可以做到这一点)。目前,我们正在手动修复该问题,因为它只有少量记录,但这可能并不总是正确的 我遇到的问题是,我需要在R中复制它们的矩阵数组。有多个条件,如果它们满足条件,应该用1标记,如下所示: 我需要能够评估12列中的一列中是否有34个潜在字符串(或部分字符串(在SAS中,冒号将比较值缩短为与评估值相同的长度并进行比较)(例如:Q16表示字符串只需要从Q16开始)。此外,12个字段中的任何一个都可能有一个值,但在后面的字段中会变得更稀疏 如果可能的话,我正试图找到最有效、最紧凑的方法 对于更复杂的问题,我在R还是有点生疏,所以我被阻碍了。 我尝试了一些方法来处理grep和grepl,但都没有结果。 当我尝试regex时,我尝试在ifelse中单独使用每个字符串,然后我还尝试了一个带有“|”运算符的较大字符串,但也没有成功。我还尝试了base(apply)和dplyr方法 感谢您的帮助 数据结构如下: 代码示例数据:R 跨多个列匹配多个字符串,并创建一个yes/no(1/0)列,r,R,编辑以添加代码: 我试图复制一位使用SAS的同事的一些工作。SAS中的导入存在问题,它将文本(匹配布尔值)转换为数字 这项工作的目的是确定要传递的特定记录,因此我们需要将值保留为最初导入的值(我认为R可以做到这一点)。目前,我们正在手动修复该问题,因为它只有少量记录,但这可能并不总是正确的 我遇到的问题是,我需要在R中复制它们的矩阵数组。有多个条件,如果它们满足条件,应该用1标记,如下所示: 我需要能够评估12列中的一列中是否有34个潜在字符串(或部分字符串(在SAS中,冒号将比较值缩短为与评
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)