【问题标题】:Finding kewords in texts and create separate columns with the words在文本中查找关键字并使用这些词创建单独的列
【发布时间】:2019-09-11 10:29:36
【问题描述】:

我正在根据模式搜索字符串:找到关键字 car0-10 之前的一侧(关键字 car 后跟从 0 到 10 的数字)。如果我找到关键字,我想将它们添加到新列(即left 和/或right)。如果没有关键字,我想添加'x'标记或NA。

我需要找到这个短语:on the right car5on the left car2。这些短语有一个共同的字符串模式(左/右+汽车+数字)。我试图弄清楚如何找到它们并在新列中添加汽车+号码。

text.v <- c("Max","John")
text.t <- c("True story about the area on the left car2, and a parking on the right car4 not far away","but there is a garage on the right car3 in another place")
#View(text.v)

text.data <- cbind(text.v,text.t)

View(text.data)

我拥有的数据:

|text.v|text.t|
|Max   | True story about the area on the left car2, and a parking on 
|John  |but there is a garage on the right car3 in another place

预期结果:

|text.v|text.t|left | right
|Max   | True story about the area on the left car2, and a parking on |car2|car4
|John  |but there is a garage on the right car3 in another place  |x|car3

如果有任何快速的方法,我想知道使用正则表达式或其他方式的方法。作为一个额外的功能,我想知道是否可以添加关键字的计数(例如,car2 在单词的右侧出现两次,right。)

【问题讨论】:

    标签: r regex string dataframe


    【解决方案1】:

    除了 Ronak 的回答,我留下代码来处理您的其他问题。在这里,我创建了一个数据集,该数据集比您的数据集要复杂一些,以考虑额外的问题。与 Ronak 类似,我创建了两个列。不同之处在于我为每一行创建了一个字符串,包括所有汽车。例如,参见temp 中的第二行。

    对于额外的问题,我创建了另一个数据框。 leftright 中可能有多辆汽车。我梳理了leftright 中的字符串,并展开了数据框。这是out。然后,我总结了左右车的频率,并合并了两个数据集。

    library(tidyverse)
    library(stringi)
    
    group_by(mydf, person) %>%
    mutate(left = stri_extract_all_regex(str = text,
                                         pattern = "(?<=on the left )car[0-9]+?") %>%
                  unlist %>% toString,
           right = stri_extract_all_regex(str = text,
                                     pattern = "(?<=on the right )car[0-9]+?") %>%
                  unlist %>% toString) %>%
    ungroup-> temp
    
    temp
    
    person text                                                                                      left  right     
    <chr>  <chr>                                                                                     <chr> <chr>     
    1 Max    Ana is on the left car2. Bob is on the right car4. They are not far away from each other. car2  car4      
    2 John   I saw a garage on the right car1. There is a garage on the right car3.                    NA    car1, car3
    3 Ana    There is a garage on the right car3. There is another garage on the right car3.           NA    car3, car3
    
    
    dplyr::select(temp, person, left, right) %>%
           Reduce(f = separate_rows_, x = c("left", "right")) -> out
    
    count(out, person, left, name = "left_total") %>%
    full_join(count(out, person, right, name = "right_total")) 
    
    person left  left_total right right_total
      <chr>  <chr>      <int> <chr>       <int>
    1 Ana    NA             2 car3            2
    2 John   NA             2 car1            1
    3 John   NA             2 car3            1
    4 Max    car2           1 car4            1
    

    另一种解决方案

    另一种方法是将 quanteda 包与 tidyverse 包一起使用。这更容易找到词频。您仍然需要修改docname。但这很容易做到。

    library(quanteda)
    
    kwic(mydf$text, pattern = "car[0-9]+?",
         window = 1, valuetype = "regex") %>%
    as.data.frame %>%
    dplyr::select(docname, pre, keyword) %>%
    count(docname, keyword, pre, name = "frequency")
    
      docname keyword pre   frequency
      <chr>   <chr>   <chr>     <int>
    1 text1   car2    left          1
    2 text1   car4    right         1
    3 text2   car1    right         1
    4 text2   car3    right         1
    5 text3   car3    right         2
    

    数据

      person                                                                                      text
    1    Max Ana is on the left car2. Bob is on the right car4. They are not far away from each other.
    2   John                    I saw a garage on the right car1. There is a garage on the right car3.
    3    Ana           There is a garage on the right car3. There is another garage on the right car3.
    

    【讨论】:

    • 谢谢!!!你们都明白这一点:) 欣赏这一点,请问是否有一些方法可以做到 1) 比使用 RE 更快? 2)或其他方法,如标记词然后搜索? (让整个过程更快?如果你有一些这样的项目...... :) 另外,如果有大约 10000 份数字 A4 论文以这种方式进行分析,我可以在哪里阅读有关 R 内存要求的信息?
    • @HappyMan 你可能想检查一下 quanteda 包。
    • 会检查它:) thx,只是我发现代码中的NA被量化了,这正常吗?像 john 和 ana 有 NA 但它显示 2 ?谢谢朋友
    • @HappyMan 安装软件包后,使用mydf 运行此代码。 kwic(mydf$text, pattern = "car[0-9]+?", window = 2, valuetype = "regex")。这条线可能会给你一些启发。
    • @HappyMan 我为你添加了 quanteda 版本。我希望这会对你有所帮助。
    【解决方案2】:

    我们可以使用str_extract,分别得到“左”和“右”字后面的车号。如果未找到匹配项,则返回 NA,稍后可以将其更改为我们想要的任何值。

    library(dplyr)
    library(stringr)
    
    text.data %>%
       mutate(left = str_extract(text.t, "(?<=left) car\\d+"), 
              right = str_extract(text.t, "(?<=right) car\\d+")) %>%
       select(left, right) #To display results
    
    #   left right
    #1  car2  car4
    #2  <NA>  car3
    

    数据

    text.data <- data.frame(text.v,text.t)
    

    【讨论】:

    • 感谢您的回复,您有使用不同方法的速度台吗?
    猜你喜欢
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多