【问题标题】:Mapping the topic of the review in R在 R 中映射评论的主题
【发布时间】:2020-10-12 11:28:53
【问题描述】:

我有两个数据集,Review Data & Topic Data

我的审核数据

的Dput代码
structure(list(Review = structure(2:1, .Label = c("Canteen Food could be improved", 
"Sports and physical exercise need to be given importance"), class = "factor")), class = "data.frame", row.names = c(NA, 
-2L))

我的主题数据

的Dput代码
structure(list(word = structure(2:1, .Label = c("canteen food", 
"sports and physical"), class = "factor"), Topic = structure(2:1, .Label = c("Canteen", 
"Sports "), class = "factor")), class = "data.frame", row.names = c(NA, 
-2L))

我的 Desired Output 的输出,我想查找出现在 Topic Data 中的单词并将其映射到 Review Data

structure(list(Review = structure(2:1, .Label = c("Canteen Food could be improved", 
"Sports and physical exercise need to be given importance"), class = "factor"), 
    Topic = structure(2:1, .Label = c("Canteen", "Sports "), class = "factor")), class = "data.frame", row.names = c(NA, 
-2L))

【问题讨论】:

  • 您应该共享可重现的数据。您可以使用dput 函数来帮助共享您的数据集。
  • 嗨@Suhas U - 如果您以人们可以复制粘贴到他们的R会话中的格式提供数据,那么您更有可能在这里获得帮助 - 例如,看看dput
  • 嘿@DanielO,感谢您的建议,我刚刚更新了我的代码!

标签: r dplyr text-mining tm tidytext


【解决方案1】:

你想要的是一个模糊连接。这是寻找严格子字符串(但不区分大小写)的蛮力:

library(dplyr)
review %>%
  full_join(topic, by = character()) %>% # full cartesian expansion
  group_by(word) %>%
  mutate(matched = grepl(word[1], Review, ignore.case = TRUE)) %>%
  ungroup() %>%
  filter(matched) %>%
  select(-word, -matched)
# # A tibble: 2 x 2
#   Review                                                   Topic    
#   <fct>                                                    <fct>    
# 1 Sports and physical exercise need to be given importance "Sports "
# 2 Canteen Food could be improved                           "Canteen"

在使用grepl 进行测试之前,它会执行帧的笛卡尔连接,这有点蛮力,但是......你无法真正避免其中的某些部分。

您还可以使用fuzzyjoin 包,它用于在模糊事物上加入(适当命名)。

fuzzyjoin::regex_left_join(review, topic, by = c(Review = "word"), ignore_case = TRUE)
# Warning: Coercing `pattern` to a plain character vector.
#                                                     Review                word   Topic
# 1 Sports and physical exercise need to be given importance sports and physical Sports 
# 2                           Canteen Food could be improved        canteen food Canteen

警告是因为您的列是factors,而不是character,它应该是无害的。如果要隐藏警告,可以使用suppressWarnings(有点强);如果您想阻止警告,请将所有适用的列从 factor 转换为 character(例如,topic[] &lt;- lapply(topic, as.character),与 review$Review 相同,但如果您有数字列,请修改它)。

【讨论】:

    【解决方案2】:

    这里是业余爱好者。我使用 base R 而不是 dplyr 来做到这一点,因为我不擅长连接函数。

    下面,初始化你的 dfs。我添加了更多示例以确保一切正常。也选择不使用因子,让后面的字符串分配变得混乱。

    # initialize your dfs
    review <- data.frame("Review" = c("Canteen Food could be improved", 
                                      "Sports and physical exercise need to be given importance",
                                      "canteen food x2",
                                      "this is my sports and physical",
                                      "SPORTS AND PHYSICAL",
                                      "meme",
                                      "canteen and food",
                                      "this is my meme",
                                      "memethis"
                                      ),
                         stringsAsFactors = F)
    
    topic <- data.frame("word" = c("canteen food", "sports and physical", "meme"), 
                        "Topic" = c("Canteen", "Sports", "meme_cat"),
                        stringsAsFactors = F)
    

    然后只需使用一些嵌套的 for 循环来迭代您想要的单词,找到匹配的字符串,并分配相关的主题。并在 for 循环之前初始化所有内容。

    # initialize new column to write into in loop
    review <- cbind(review, "Topic" = rep(NA, nrow(review)))
    
    # initialize before for loop
    a <- rep(F, nrow(topic))
    
    # loop over words in topic and find string matches in review. if so, assign review$topic = Topic
    for (i in 1:nrow(topic)) {
      for(j in 1:nrow(review)) {
        a[j] <- grepl(topic$word[i], review$Review[j], ignore.case=T)
      }
      if (any(a)) {
        review$Topic[a] = topic$Topic[i]
      }
    
    review
    #                                                    Review    Topic
    #1                           Canteen Food could be improved  Canteen
    #2 Sports and physical exercise need to be given importance   Sports
    #3                                          canteen food x2  Canteen
    #4                           this is my sports and physical   Sports
    #5                                      SPORTS AND PHYSICAL   Sports
    #6                                                     meme meme_cat
    #7                                         canteen and food     <NA>
    #8                                          this is my meme meme_cat
    #9                                                 memethis meme_cat
    

    【讨论】:

    • 这显示了很多努力,user13214050!双循环没有错,但是grepl 使用向量可以提高效率:第一个参数 (pattern=) 的长度必须为 1,而第二个参数 (x=) 可以任何长度。您可能会移除 for (j 循环并分配 a &lt;- grepl(...)。 (顺便说一句:最后缺少一个右大括号。)
    猜你喜欢
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2017-06-30
    • 2011-02-07
    • 2020-08-18
    • 2020-03-23
    • 1970-01-01
    相关资源
    最近更新 更多