【问题标题】:why cannot get rid of first word after white space and brackets with sub, in R?为什么不能在 R 中去掉空格和括号后的第一个单词?
【发布时间】:2021-06-07 16:42:42
【问题描述】:

我正在努力摆脱:

  1. 空格和/或第一个单词和之后的单词;
  2. 想去掉第一个单词后的括号
  3. 或者只保留列中的第一个单词

这是我拥有的数据集类型:

structure(list(med_name = c("Co-amoxiclav", "doxycycline", "Gentamicin", 
"Co-trimoxazole", "Sodium Chloride 0.9% infusion (ANES) 20 mL + Vancomycin", 
"Piperacillin + Tazobactam (contains penicillin)"), new1 = c("Co-amoxiclav", 
"doxycycline", "Gentamicin", "Co-trimoxazole", "Sodium Chloride", 
"Piperacillin + Tazobactam (contains penicillin)"), new2 = c(NA, 
NA, NA, NA, "Vancomycin", "Tazobactam (contains penicillin)")), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

使用下面的代码,我相信我摆脱了空格之后的第一个单词和括号中的单词。实际上只想在new_1和new_2每一列中保留第一个单词

dt_test_1 <- dt_test %>%
  dplyr::mutate(keep_first_letter_new_1 = gsub(' [A-z ]*', "", new1), 
                keep_first_letter_new_2 = gsub(' [A-z]*', "", new2), 
                remove_brackets_new_1 = gsub("( )", "", keep_first_letter_new_1), 
                remove_brackets_new_2 = gsub("( )", "", keep_first_letter_new_2)
                )

但正如在 dt_test_1 中观察到的 - 我没有得到我想要的输出。检查最后两列以及每列中的最后一行。这是我得到的:

structure(list(med_name = c("Co-amoxiclav", "doxycycline", "Gentamicin", 
"Co-trimoxazole", "Sodium Chloride 0.9% infusion (ANES) 20 mL + Vancomycin", 
"Piperacillin + Tazobactam (contains penicillin)"), new1 = c("Co-amoxiclav", 
"doxycycline", "Gentamicin", "Co-trimoxazole", "Sodium Chloride", 
"Piperacillin + Tazobactam (contains penicillin)"), new2 = c(NA, 
NA, NA, NA, "Vancomycin", "Tazobactam (contains penicillin)"), 
    keep_first_letter_new_1 = c("Co-amoxiclav", "doxycycline", 
    "Gentamicin", "Co-trimoxazole", "Sodium", "Piperacillin+(contains)"
    ), keep_first_letter_new_2 = c(NA, NA, NA, NA, "Vancomycin", 
    "Tazobactam(contains)"), remove_brackets_new_1 = c("Co-amoxiclav", 
    "doxycycline", "Gentamicin", "Co-trimoxazole", "Sodium", 
    "Piperacillin+(contains)"), remove_brackets_new_2 = c(NA, 
    NA, NA, NA, "Vancomycin", "Tazobactam(contains)")), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

因此,我的问题是,为什么我没有得到我想要的输出?

这是我想要的输出:

structure(list(med_name = c("Co-amoxiclav", "doxycycline", "Gentamicin", 
"Co-trimoxazole", "Sodium Chloride 0.9% infusion (ANES) 20 mL + Vancomycin", 
"Piperacillin + Tazobactam (contains penicillin)"), new1 = c("Co-amoxiclav", 
"doxycycline", "Gentamicin", "Co-trimoxazole", "Sodium Chloride", 
"Piperacillin + Tazobactam (contains penicillin)"), new2 = c(NA, 
NA, NA, NA, "Vancomycin", "Tazobactam (contains penicillin)"), 
    keep_first_letter_new_1 = c("Co-amoxiclav", "doxycycline", 
    "Gentamicin", "Co-trimoxazole", "Sodium", "Piperacillin+(contains)"
    ), keep_first_letter_new_2 = c(NA, NA, NA, NA, "Vancomycin", 
    "Tazobactam(contains)"), remove_brackets_new_1 = c("Co-amoxiclav", 
    "doxycycline", "Gentamicin", "Co-trimoxazole", "Sodium", 
    "Piperacillin"), remove_brackets_new_2 = c(NA, NA, NA, NA, 
    "Vancomycin", "Tazobactam")), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"))

最后两列是我需要的最后一列。

【问题讨论】:

  • 您应该精确问题以获得直接的答案。您的正则表达式通常处于关闭状态:1) gsub(' [A-z ]*', "", new1) 删除所有空格序列,然后删除零个或多个空格、ASCII 字母以及 [\`]^_ 字符,以及 2) gsub("( )", "", keep_first_letter_new_1) 删除所有空格。
  • @WiktorStribiżew - 我是自然语言处理的新手,很难具体说明
  • 你是否意识到你所有的前 3 点都是关于只保留第一个单词?从这些要求来看,sub(" .*", "", x) 就是您所需要的。
  • 在发布之前请考虑真正的需求。
  • @WiktorStribiżew 然而,这是不同情况下的问题。我已经提供了问题,我已经提供了我正在使用的代码,我还提供了输出,然后是所需的答案。我确实相信你应该为新手学习留下一个杠杆,最好的学习方法是不要让他们感到困惑:)。只要继续我给出的假数据集,看看我有多清楚,不管未使用的概念如何(我还是正则表达式的新手)。但如果证明你没有去检查。坐在一边,判断创建这篇文章背后的辛勤工作不是它应该工作的方式。

标签: r tidyverse gsub


【解决方案1】:

在下面的代码中,x 只是您提供的第一个数据结构。我发现用“+”号分割字符串然后提取第一个单词更容易。可以通过stringr 包中的str_trim 修剪周围的空间。

med=x$med_name
library(stringr)
strings=str_split(med, "\\+")
out=lapply(strings, function(x) {
  str_trim(str_extract(x, " *(\\S*)"))}
)
out
[[1]]
[1] "Co-amoxiclav"

[[2]]
[1] "doxycycline"

[[3]]
[1] "Gentamicin"

[[4]]
[1] "Co-trimoxazole"

[[5]]
[1] "Sodium"     "Vancomycin"

[[6]]
[1] "Piperacillin" "Tazobactam"

new_1=c()
new_2=c()
for (i in 1:6) {
  new_1[i]=out[[i]][1]
  new_2[i]=out[[i]][2]
}        
transform(x[-c(2,3)], new_1=new_1, new_2=new_2)

                                                 med_name          new_1      new_2
1                                            Co-amoxiclav   Co-amoxiclav       <NA>
2                                             doxycycline    doxycycline       <NA>
3                                              Gentamicin     Gentamicin       <NA>
4                                          Co-trimoxazole Co-trimoxazole       <NA>
5 Sodium Chloride 0.9% infusion (ANES) 20 mL + Vancomycin         Sodium Vancomycin
6         Piperacillin + Tazobactam (contains penicillin)   Piperacillin Tazobactam

【讨论】:

  • 这是在我自己的数据集上做的吗?然后应用答案?
  • 它使用了您在“这是我拥有的数据集类型:”下粘贴的数据集
  • 对此我深表歉意!我现在看到了。那么我很抱歉标记了这个!干杯。
  • 我必须收回我的话,它不起作用,因为我有 250 个不同的级别,而且所有的形状和形式都非常不同。
【解决方案2】:

在尝试执行所有不需要的字符的修剪时,我似乎错过了一个命令。因此,我认为错误是我去掉了上面的空格,然后括号中的单词与第一个单词成为一个单词。然后,当我申请删除括号中的单词时,我没有成功,因为单词之间没有空格。

因此,我在删除不需要的字符和单词时保持特定的顺序:

  1. 我删除了空白,但是
  2. 添加一个新的 - 删除单词之间的连字符,然后
  3. 我正在删除第一个单词之后的第二个单词。

这是我为解决上面发布的问题所做的工作:

  dt_test_1 <- dt_test %>%
      dplyr::mutate(keep_first_letter_new_1 = gsub(' [A-z ]*', "", new1), 
                    keep_first_letter_new_2 = gsub(' [A-z]*', "", new2), 
                    remove_hypen_new_1 = gsub("-", "", keep_first_letter_new_1), 
                    remove_hypen_new_2 = gsub("-", "", keep_first_letter_new_2), 
                    remove_any_words_after_first_new1 =    gsub("\\s([^\\)]+\\)",remove_hypen_new_1, "", remove_hypen_new_1), 
                    remove_any_words_after_first_new2 = gsub("\\s([^\\)]+\\)",remove_hypen_new_1, "", remove_hypen_new_2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2020-08-27
    • 1970-01-01
    • 2019-08-19
    • 2015-07-19
    • 1970-01-01
    • 2020-12-13
    相关资源
    最近更新 更多