【问题标题】:Recognize patterns in column, and add them to column in Data frame识别列中的模式,并将它们添加到数据框中的列
【发布时间】:2018-11-13 14:09:44
【问题描述】:

得到一个包含 50 个关键字的列:

Keyword1 
Keyword2
Keyword3
KeywordN=50

此外,我得到了一个包含两列的数据框:标题和摘要。

Title                    Abstract 
Rstudio Keyword1        A interesting program language keyword2  
Python Keyword3         A interesting program keyword3 language 

我想获得一个额外的列(我们称之为关键字),如果关键字名称出现在标题或摘要中,则会出现在该列中,如下所示:

Title             Abstract                                   Keywords
Rstudio Keyword1 A interesting program language keyword2  Keyword1, keyword2
Python Keyword2  A interesting program keyword3 language  Keyword2, Keyword3

我唯一能“解决”这个问题的方法是制作一个二进制列(如果模式匹配)。 (grepl 函数),但这不是我们想要的解决方案……

【问题讨论】:

    标签: r regex text preprocessor


    【解决方案1】:

    在基地R:

    • 这处理标点符号、空格、行尾/行首。
    • 关键字可以包含空格和一些标点符号(但不是全部)
    • 新列的关键字保持原关键字向量大小写:

    代码

    ind  <- sapply(paste0('(^|[ [:punct:]])',tolower(keywords),'($|[ [:punct:]])'),grep,tolower(paste(df$Title,df$Abstract)))
    ind[lengths(ind)==0] <- NA # for cases where no keyword is found
    ind2 <- do.call(rbind,Map(data.frame,keyword=keywords,i=ind))
    ind3 <- aggregate(keyword ~ i,ind2,paste,collapse=', ')
    df$keywords[ind3$i] <- ind3$keyword
    df$keywords[is.na(df$keywords)] <- "" # replacing NAs with empty strings
    #              Title                                Abstract           keywords
    # 1 Rstudio Keyword1 A interesting program language keyword2 Keyword1, Keyword2
    # 2  Python Keyword2 A interesting program keyword3 language Keyword2, Keyword3
    

    数据

    keywords <- c("Keyword1", "Keyword2", "Keyword3")
    
    df <- read.table(text="Title                    Abstract 
                     'Rstudio Keyword1'        'A interesting program language keyword2'  
                     'Python Keyword2'         'A interesting program keyword3 language'",h=T,strin=F)
    

    【讨论】:

    • 因修改问题的数据失败而更新
    • > ind2
    • 它对我来说很好用......而且都是基础R......其他人可以复制这个问题吗?
    • 无论如何这不是我的代码,我不使用keywords1
    • 正确,keywords1 == 我的代码中的关键字 :-)。所以这不应该是区别。 (抱歉造成混淆)
    【解决方案2】:
    cbind(dat,Keywords=do.call(paste,c(sep=",",Map(sub,paste0(".*(",paste(keywords,collapse="|"),").*"),"\\1",dat,TRUE))))
                 Title                                Abstract          Keywords
    1 Rstudio Keyword1 A interesting program language keyword2 Keyword1,keyword2
    2  Python Keyword3 A interesting program keyword3 language Keyword3,keyword3
    

    keywords=paste0("Keyword",1:3)

    dat=read.table(text="Title                    Abstract 
    'Rstudio Keyword1'        'A interesting program language keyword2'  
    'Python Keyword3'         'A interesting program keyword3 language'",h=T,strin=F)
    

    这条线可能看起来很长:细分:

    a=paste0(".*(",paste(keywords,collapse="|"),").*")
    b=do.call(paste,c(sep=",",Map(sub,a,"\\1",dat,TRUE)))
    cbind(dat,keywords=b)
                 Title                                Abstract          keywords
    1 Rstudio Keyword1 A interesting program language keyword2 Keyword1,keyword2
    2  Python Keyword3 A interesting program keyword3 language Keyword3,keyword3
    

    【讨论】:

      【解决方案3】:

      使用strsplit 的另一种方法(也在基础 R 中):

      ls <- strsplit(tolower(paste(df$Title, df$Abstract)), 
                             "(\\s+)|(?!')(?=[[:punct:]])", perl = TRUE)    
      
      df$Keywords <- do.call("rbind", 
                     lapply(ls, function(x) paste(unique(x[x %in% tolower(keywords)]), 
                     collapse = ", ")))
      
      #             Title                                Abstract           Keywords
      #1 Rstudio Keyword1 A interesting program language keyword2 keyword1, keyword2
      #2  Python Keyword2 A interesting program keyword3 language keyword2, keyword3
      

      样本数据

      df <- data.frame(Title = c("Rstudio Keyword1", "Python Keyword2"), 
                       Abstract = c("A interesting program language keyword2",  
                                    "A interesting program keyword3 language"), 
                       stringsAsFactors = F)
      
      keywords <- paste0("Keyword", 1:4)
      

      【讨论】:

      • 解决方案有效。但是还有另一种可能性,即您只获得独特的价值吗?例如:如果第一行包含:keyword1、keyword1 和keyword1,那么结果将是:“keyword1”、“keyword1”、keyword1”。理想情况下是一次:“keyword1”(因此每行的唯一值)跨度>
      • 如果关键字出现在标点符号之后则失败
      • 如果关键字包含空格也会失败
      • @Moody_Mudskipper 我对标点符号问题进行了编辑。
      • 谢谢,但是:df$Keywords
      【解决方案4】:
      Title<-as.character(c("Rstudio Keyword1","Python Keyword3"))
      Abstract<-as.character(c("A interesting program language keyword2"," A interesting program keyword3 language"))
      example1.data <- data.frame(Title,Abstract)
      
      
      #loop answer
      f<-length(example1.data)
      example1.data$Keyword <- NA
      
      for (i in 1:nrow(example1.data)){
      testA[i]<-regmatches(example1.data$Title[i], regexpr("(Keyword|keyword) ([0-9])", example1.data$Title[i]))
      testB[i]<-regmatches(example1.data$Abstract[i], regexpr("(Keyword|keyword)([0-9])", example1.data$Abstract[i]))
      example1.data$Keyword[i]<-paste(testA[i],testB[i],  sep=", ")
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-02
        • 1970-01-01
        • 2021-12-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多