【问题标题】:Extracting text based on condition in R根据R中的条件提取文本
【发布时间】:2017-06-19 23:04:29
【问题描述】:

我对 R 比较陌生。我有一个名为 RN 的字符变量,需要根据 RN 上的某些条件将其文本提取为 2 个变量 [named_RNgeneral_RN]。这就是想要的结果(现在,named_RNgeneral_RN 是空白的 - 我不知道如何编写这部分代码,这就是我需要帮助的地方!):

RN                                              named_RN         general_RN
RP4A60D26L (Pentazocine)                        Pentazocine
0 (Complement C4)                                                Complement C4
0 (Aminocap) U6206 (Amino)                      Amino            Aminocap
N3R30 (Amiodarone) 0 (Benzo) 0 (Ferri)          Amiodarone       Benzo, Ferri

如您所见,我正在尝试提取括号内的信息。但是,如果代码为 0,我想从 RN 提取到 general_RN,如果代码非零,我想提取到 named_RN

我遇到的主要问题是我无法通过0 (0 ( [后一个中0 之前的空格,因为有时0 代码在RN 的文本中间开始是最后一行的情况] 因为named_RN 的某些代码以0 ( 结尾,与最后一行的情况一样。

请指教。

谢谢!

【问题讨论】:

  • 所以 RN 包含一个对的列表,其中对的第一个元素是“0”或其他东西,对的第二个元素是括号中的项目?
  • 当然,这是看待它的一种方式。虽然它不是列表格式。这只是性格。

标签: r regex text data-manipulation text-extraction


【解决方案1】:

这是一种方法。基本上,我创建了一个新列,其中更容易检测到匹配项。然后,我将括号内部与regmatches匹配。

df <- read.table(text="RN
'RP4A60D26L (Pentazocine)'
'0 (Complement C4)'
'0 (Aminocap) U6206 (Amino)'
'N3R30 (Amiodarone) 0 (Benzo) 0 (Ferri)'",header=TRUE,stringsAsFactors=FALSE)

df$RN_temp <- gsub("^[0] "," general_RN",df$RN) #replace leading 0s w/ general_RN
df$RN_temp <- gsub(" [0] "," general_RN",df$RN_temp) #replace other " 0 "
df$RN_temp <- gsub(" \\("," named_RN(",df$RN_temp) #replace rest w/ named_RN
df$RN_temp

df$named_RN <- regmatches(df$RN_temp,gregexpr("(?<=named_RN\\().*?(?=\\))",
                df$RN_temp, perl=TRUE))
df$general_RN <- regmatches(df$RN_temp,gregexpr("(?<=general_RN\\().*?(?=\\))", 
                  df$RN_temp, perl=TRUE))
df$RN_temp <- NULL
df

编辑 转换为data.frame。我使用lapply(df$named_RN, function(x) ifelse(is.null(x), NA, x)) 将缺失值(NULL)更改为NA。

df$named_RN <- unlist(lapply(df$named_RN, function(x) ifelse(is.null(x), NA, x)))
df$general_RN <- unlist(df$general_RN)

'data.frame':   4 obs. of  3 variables:
 $ RN        : chr  "RP4A60D26L (Pentazocine)" "0 (Complement C4)" "0 (Aminocap) U6206 (Amino)" "N3R30 (Amiodarone) 0 (Benzo) 0 (Ferri)"
 $ named_RN  : chr  "Pentazocine" NA "Amino" "Amiodarone"
 $ general_RN: chr  "Complement C4" "Aminocap" "Benzo" "Ferri"
                                      RN    named_RN    general_RN
1               RP4A60D26L (Pentazocine) Pentazocine              
2                      0 (Complement C4)             Complement C4
3             0 (Aminocap) U6206 (Amino)       Amino      Aminocap
4 N3R30 (Amiodarone) 0 (Benzo) 0 (Ferri)  Amiodarone  Benzo, Ferri

【讨论】:

  • 哇,这行得通!我也很喜欢你的算法。我需要更多地研究 regmatches/gregexpr 并彻底了解这些功能。所有的 (?/.*
  • 我不是正则表达式专家,但我在这个网站上学习了基础知识:regexone.com
  • 我确实有一个(非常基本的)问题。您的代码导致我的数据框被列为c("Benzo", "Ferri")character(0)(如果它为空)。如何将其更改为简单的 Benzo, Ferri 和一个空字符串?不知道为什么我不能取消列表...不过我会多玩一点。
  • 我不能,例如df$general_RN &lt;- unlist(df$general_RN),因为Error in $(*tmp*, general_RN, value = c("Drug Combinations", : replacement has 1992 rows, data has 10479
  • hm,对于named_RN,当我希望全部保留时,它只保留每个列表的第一个元素。对于general_RN,我收到以下错误Error in $(*tmp*, general_RN, value = c("Drug Combinations", : replacement has 1992 rows, data has 10479
【解决方案2】:

虽然我确实使用了gsub,但我也使用了来自stringrstring_match_all 包裹。要解决您提到的问题(代码可能包含 0),您可以使用 \\b 断言来限制 0 不是较长字符串的一部分。

名字_RN

library(stringr)

## named_RN 
namedTemp = gsub("\\b0\\s+\\((.*?)\\)\\s*", "", RN)
namedTemp = sapply(str_extract_all(namedTemp, "\\([^\\)]+\\)"), 
            paste, collapse=", ")
(named_RN  = gsub("[()]", "", namedTemp))
[1] "Pentazocine" ""            "Amino"       "Amiodarone"

然后general_RN

## general_RN 
generalTemp = sapply(str_extract_all(RN, "\\b0\\s+\\((.*?)\\)"), 
    paste, collapse=", ")
generalTemp = gsub("\\b0\\s+", "", generalTemp)
(general_RN = gsub("[()]", "", generalTemp))
[1] ""              "Complement C4" "Aminocap"      "Benzo, Ferri" 

【讨论】:

  • 哦,这几乎成功了!除了一些 named_RN 代码看起来像 9002-68-0 在这种情况下,您的代码将其标记为 general_RN 而不是 named_RN.
猜你喜欢
  • 2017-10-02
  • 2020-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2021-06-18
  • 2022-06-24
  • 1970-01-01
相关资源
最近更新 更多