【问题标题】:Finding keywords in text and appending keyword topic在文本中查找关键字并附加关键字主题
【发布时间】:2019-07-23 17:16:09
【问题描述】:

我有一个大型文本数据框,我想在其中查找关键字。关键字还应用了类别。我需要帮助弄清楚如何附加 2 列,1 列带有找到的关键字,1 列带有关联的类别

我认为我有正确的代码来创建关键字列;但是,我不知道如何创建类别列。

#Generate sample data
text <- tibble(phrases = c("Hello my name is Bob", "I wasted time when I was that age", "What time is the party?"))
keys    <- tibble(words = c("name","age","time"),categories = c("demographic","demographic","details"))

#Find keyword matches
text_match <- sapply(paste0(keys$words), grepl, text$phrases) %>% 
              as_tibble() %>% 
              mutate(Keywords = apply(., 1, function(x) paste(colnames(.)[x == 1], collapse = " | ")))

这会正确生成关键字列:

  name  age   time  Keywords                     
1 TRUE  FALSE FALSE name         
2 FALSE TRUE  TRUE  age | time
3 FALSE FALSE TRUE  time

但是我怎样才能创建类别列。我想要这样的东西:

  name  age   time  Keywords   Category                           
1 TRUE  FALSE FALSE name       demographic          
2 FALSE TRUE  TRUE  age | time demographic | details
3 FALSE FALSE TRUE  time       details

【问题讨论】:

    标签: r text merge


    【解决方案1】:

    如果您愿意使用tidytexttidyr,您可以获得准确的输出。但根据您拥有的关键字数量,您可能希望在下面的第 1 步停止。

    首先我在文本 tibble 中添加一个 id。然后使用unnest_tokens 将此数据取消嵌套到 df1 中。将此数据与 step0 中的关键字合并。在第 1 步中,折叠每个 id 的关键字和类别。在第 2 步中,为第 0 步中找到的每个关键字添加一个 TRUE 列,并传播此数据并将其与第 1 步的结果合并,以提供所需的输出。

    library(tidytext)
    library(tidyr)
    
    text <- text %>% mutate(id = row_number())
    df1 <- unnest_tokens(text, "words", input = phrases)
    
    step0 <- df1 %>% inner_join(keys)
    # Joining, by = "words"
    
    step1 <- step0 %>% 
      group_by(id) %>%
      summarise(Keywords = paste(words ,collapse = " | "),
                Category = paste(categories, collapse = " | "))
    
    step1
    # A tibble: 3 x 3
         id Keywords   Category             
      <int> <chr>      <chr>                
    1     1 name       demographic          
    2     2 time | age details | demographic
    3     3 time       details  
    
    step2 <- step0 %>% 
      mutate(value = TRUE) %>% 
      select(id, words, value) %>% 
      spread(words, value = value, fill = FALSE) %>% 
      inner_join(step1)
    
    # Joining, by = "id"
    
    step2
    # A tibble: 3 x 6
         id age   name  time  Keywords   Category             
      <int> <lgl> <lgl> <lgl> <chr>      <chr>                
    1     1 FALSE TRUE  FALSE name       demographic          
    2     2 TRUE  FALSE TRUE  time | age details | demographic
    3     3 FALSE FALSE TRUE  time       details   
    

    【讨论】:

    • 完美答案!我有使用 Tidytext 的经验,我什至没想过要使用它。非常感谢。
    【解决方案2】:

    如果您的关键字列表不是很大,您可以使用 dplyr 中的 case_when。即:

    text_match$category <- case_when(text_match$keywords== "name" ~ "demographic"
    

    产量:

    # A tibble: 3 x 5
      name  age   time  Keywords   category   
      <lgl> <lgl> <lgl> <chr>      <chr>      
    1 TRUE  FALSE FALSE name       demographic
    2 FALSE TRUE  TRUE  age | time NA         
    3 FALSE FALSE TRUE  time       NA  
    

    【讨论】:

    • 感谢您的回复。不幸的是,关键字列表相当大(+150 个条目)。另外,当有多个关键字时,“case_when”是否可以工作,如上面的第二种情况(年龄 | 时间)?
    • phiver 的回答可能会让你到达你需要的地方,但以防万一你最终使用 case_when 将来是的,你可以为每个案例做多个。您可以将 & 用于跨列的多个匹配项,也可以使用逗号分隔多个或。
    猜你喜欢
    • 2013-01-13
    • 2019-08-26
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 2013-01-13
    • 1970-01-01
    相关资源
    最近更新 更多