如何只捕获R中字符串的一部分?

问题描述 投票:0回答:2

我想用stringr::str_matchrebus::capture捕捉字符串的一些部分,但我无法弄清楚正确的模式。

文本可能包含一些特殊字符。就像是:

enter image description here

数据:

df <- structure(list(ID = c(1, 1, 1, 2, 2), TEXT = c("VERIFIED DATE/TIME: 24/11/2018 16:23, VERIFIED PERSON IN CHARGE: JOHN", 
"HISTORY aaaAAA# 111 FINDINGS Bb123 CONCLUSION 987CCC ccc654", 
"DIAGNOSIS abc def hij", "VERIFIED DATE/TIME: 25/10/2018 16:23, VERIFIED PERSON IN CHARGE: Mary", 
"HISTORY eeeEEE@ 111 FINDINGS Bb321 CONCLUSION 987FFF ggg654"
)), .Names = c("ID", "TEXT"), row.names = c(NA, 5L), class = "data.frame")
#   ID                                                                  TEXT
# 1  1 VERIFIED DATE/TIME: 24/11/2018 16:23, VERIFIED PERSON IN CHARGE: JOHN
# 2  1           HISTORY aaaAAA# 111 FINDINGS Bb123 CONCLUSION 987CCC ccc654
# 3  1                                                 DIAGNOSIS abc def hij
# 4  2 VERIFIED DATE/TIME: 25/10/2018 16:23, VERIFIED PERSON IN CHARGE: Mary
# 5  2           HISTORY eeeEEE@ 111 FINDINGS Bb321 CONCLUSION 987FFF ggg654

期望的输出:我想将文本分成不同的列:

  1. 验证日期/时间
  2. 经核实的人员
  3. 历史
  4. 发现
  5. 结论
  6. 诊断
df_out <- structure(list(ID = c(1, 2), `VERIFIED DATE/TIME` = c("24/11/2018 16:23,", 
"25/10/2018 16:23,"), `VERIFIED PERSON IN CHARGE` = c("JOHN", 
"Mary"), HISTORY = c("aaaAAA# 111", "eeeEEE@ 111"), FINDINGS = c("Bb123", 
"Bb321"), CONCLUSION = c("987CCC ccc654", "987FFF ggg654"), DIAGNOSIS = c("abc def hij", 
NA)), .Names = c("ID", "VERIFIED DATE/TIME", "VERIFIED PERSON IN CHARGE", 
"HISTORY", "FINDINGS", "CONCLUSION", "DIAGNOSIS"), row.names = 1:2, class = "data.frame")

码:

我尝试了以下代码,但它给了我NA:

library(stringr)
library(rebus)
str_match(df$TEXT, pattern = "VERIFIED DATE/TIME:" %R%
            capture(one_or_more(ANY_CHAR)) %R%
            "VERIFIED PERSON IN CHARGE:" %R%
            capture(one_or_more(ANY_CHAR)))
r dplyr stringr
2个回答
0
投票

结合库tmstringr。我们首先为每个ID创建一个完整的文本,同时在,FINDINGS之前添加CONCLUSION以保持一致性

library(tm)
library(stringr)
library(dplyr)
df = df%>%group_by(ID)%>%summarise(TEXT=paste(TEXT,collapse=", "))%>%mutate(TEXT=gsub("(.*)( FINDINGS.*)( CONCLUSION.*)","\\1,\\2,\\3",TEXT))
> df
# A tibble: 2 x 2
     ID TEXT                                                                                                                                        
  <dbl> <chr>                                                                                                                                       
1     1 VERIFIED DATE/TIME: 24/11/2018 16:23, VERIFIED PERSON IN CHARGE: JOHN, HISTORY aaaAAA# 111, FINDINGS Bb123, CONCLUSION 987CCC ccc654, DIAGN~
2     2 VERIFIED DATE/TIME: 25/10/2018 16:23, VERIFIED PERSON IN CHARGE: Mary, HISTORY eeeEEE@ 111, FINDINGS Bb321, CONCLUSION 987FFF ggg654 

然后,我们将我们感兴趣的名称定义为列名,并将其从字符串中删除

titles = c("VERIFIED DATE/TIME: ","VERIFIED PERSON IN CHARGE: ","HISTORY ","FINDINGS ","CONCLUSION ","DIAGNOSIS ")
df$TEXT = removeWords(df$TEXT,titles)
> df
# A tibble: 2 x 2
     ID TEXT                                                                  
  <dbl> <chr>                                                                 
1     1 24/11/2018 16:23, JOHN, aaaAAA# 111, Bb123, 987CCC ccc654, abc def hij
2     2 25/10/2018 16:23, Mary, eeeEEE@ 111, Bb321, 987FFF ggg654 

最后,我们通过,分列列并设置列的名称。

df_fin=str_split_fixed(df$TEXT, ", ",6)
colnames(df_fin)=titles
> df_fin
     VERIFIED DATE/TIME:  VERIFIED PERSON IN CHARGE:  HISTORY       FINDINGS  CONCLUSION      DIAGNOSIS    
[1,] "24/11/2018 16:23"   "JOHN"                      "aaaAAA# 111" "Bb123"   "987CCC ccc654" "abc def hij"
[2,] "25/10/2018 16:23"   "Mary"                      "eeeEEE@ 111" "Bb321"   "987FFF ggg654" "" 

0
投票

这是使用stringr的一种方式

library(tidyr)
library(dplyr)
library(stringr)


df2 <- df %>% 
  group_by(ID) %>%
  summarise(conc_text = paste(TEXT, collapse = ", ")) %>%
  mutate(verified_date = apply(str_match(conc_text, "VERIFIED DATE/TIME: (.*?),"), 1, FUN = function(x) x[2]),
         verified_person = apply(str_match(conc_text, "VERIFIED PERSON IN CHARGE: (.*?),"), 1, FUN = function(x) x[2]),
         history = apply(str_match(conc_text, "HISTORY (.*?[0-9]{3})"), 1, FUN = function(x) x[2]),
         findings = apply(str_match(conc_text, "FINDINGS (.*?[0-9]{3})"), 1, FUN = function(x) x[2]),
         conclusions = apply(str_match(conc_text, "CONCLUSION (.*[0-9]{3})"), 1, FUN = function(x) x[2]),
         diagnosis = apply(str_match(conc_text, "DIAGNOSIS (.*$)"), 1, FUN = function(x) x[2]))

首先通过ID连接文本。

假设HISTORYFINDINGSCONCLUSIONS变量以3位数字结尾,因此为什么存在[0-9]{3}表达式。使用apply函数获取匹配的字符串。

© www.soinside.com 2019 - 2024. All rights reserved.