【问题标题】:Efficient way of keyword matching in R?R中关键字匹配的有效方法?
【发布时间】:2020-06-27 18:37:17
【问题描述】:

我正在尝试匹配两个大型书目数据集(1.8M obs 和 3.9M obs)之间的关键字,它们来自记录中的各个字段:标题、作者、出版日期、出版商。

对于每个条目(1.8M),我想将字符串中的每个关键字与另一个数据集(3.9M)的每个条目中的关键字进行匹配,并返回匹配最多的行。

我想出的方法,使用来自 tidyverse 的分离()和聚集()函数,以及一些基本的 dplyr,似乎有效,但无法扩展到整个数据集。

有没有更有效(或完全更好)的方法来做到这一点?

三个关键字和字符串和代码的示例数据:

library(dplyr)
library(tidyverse)

df1 <- data.frame("df1.index" = c(1:3), 
                  "keywords" = c("2013 history interpretation oxford the tractatus univ wittgensteins", 
                                 "2014 baxi law of oxford pratiksha public secrets univ", 
                                 "2014 darwin flinching from looking on oxford scientific shell-shock"))


df2 <- data.frame("df2.index" = c(1:3), 
                  "keywords" = c("2014 darwin flinching from looking on oxford scientific theatricality",
                                 "2013 interpretation oxford tractatushistory univ wittgensteins", 
                                 "2014 baxi in india law of oxford pratiksha public rape secrets trials univ"))

#separate up to 10 keywords
df1_sep <- separate(df1, keywords, into = 
                      c("key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10"), 
                    sep = " ", remove = FALSE)
df2_sep <- separate(df2, keywords, into = 
                      c("key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10"), 
                    sep = " ", remove = FALSE)

#gather separated keywords into one column
df1_gather <- df1_sep %>% 
  gather(keys, key.match, key1:key10, factor_key = TRUE) %>% 
  distinct()
df2_gather <- df2_sep %>% 
  gather(keys, key.match, key1:key10, factor_key = TRUE) %>% 
  distinct()

#remove NAs, blanks, trim
df1_gather <- df1_gather %>% filter(!is.na(key.match))
df1_gather <- df1_gather %>% filter(key.match != "")
df1_gather$key.match <- str_trim(df1_gather$key.match)

df2_gather <- df2_gather %>% filter(!is.na(key.match))
df2_gather <- df2_gather %>% filter(key.match != "")
df2_gather$key.match <- str_trim(df2_gather$key.match)

#join, after removing some columns from df2_gather
df2_gather <- df2_gather %>% select(df2.index, key.match)

df_join <- left_join(df1_gather, df2_gather)

#remove NAs
df_join <- df_join %>% filter(!is.na(df2.index))

#tally matches for each index, then take top match
df_join <- df_join %>% group_by(df1.index, df2.index) %>% tally()
df_join <- df_join %>% group_by(df1.index) %>% top_n(1, n)

#add back keywords to review match 
df_join$df1.keywords=df1$keywords[match(df_join$df1.index, df1$df1.index)]
df_join$df2.keywords=df2$keywords[match(df_join$df2.index, df2$df2.index)] 

【问题讨论】:

    标签: r string dplyr tidyverse keyword


    【解决方案1】:

    也许这种方法对于直接使用每个关键字进行计数可能很有用。我希望这可以帮助:

    library(tidytext)
    #Separate
    df1 %>% mutate(keywords=as.character(keywords)) %>% unnest_tokens(word,keywords) -> l1
    df2 %>% mutate(keywords=as.character(keywords)) %>% unnest_tokens(word,keywords) -> l2
    #Join
    l1 %>% left_join(l2) -> l3
    l2 %>% left_join(l1) -> l4
    #Compute number of ocuurences
    table(l3$df1.index,l3$df2.index,exclude=NULL)
    table(l4$df1.index,l4$df2.index,exclude=NULL)
    

    输出:

        1 2 3 <NA>
      1 1 5 2    3
      2 2 2 9    0
      3 8 1 2    2
    
           1 2 3
      1    1 5 2
      2    2 2 9
      3    8 1 2
      <NA> 1 1 4
    

    【讨论】:

      猜你喜欢
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      相关资源
      最近更新 更多