【问题标题】:String extract from multiple columns using a list in R使用R中的列表从多列中提取字符串
【发布时间】:2018-02-09 15:21:48
【问题描述】:

我正在尝试使用列表从超过 2 列(下面给出的示例中给出的 2 列)中提取信息,并创建另一列,其中包含从任一列中找到的列表中的字符串,指定要查看的列第一的。我有下面的示例以及所需的输出是什么。希望这对我正在寻找的内容有所帮助。

A<-c("This contains NYU", "This has NYU", "This has XT", "This has FIT", 
"Something something UNH","I got into UCLA","Hello XT")
B<-c("NYU","UT","USC","FIT","UNA","UCLA", "CA")
data<-data.frame(A,B)

list <- c("NYU","FIT","UCLA","CA","UT","USC")

                        A    B
1       This contains NYU  NYU
2            This has NYU   UT
3             This has XT  USC
4            This has FIT  FIT
5 Something something UNH  UNA
6         I got into UCLA UCLA
7                Hello XT   CA 

我希望代码从列表中搜索并首先在 A 列中查找,如果找不到该字符串,则在 B 列中查找,如果没有则给出 null。通过查看列表,我希望所需的输出如下所示。

                        A    B    C
1       This contains NYU  NYU  NYU
2            This has NYU   UT  NYU
3             This has XT  USC  USC
4            This has FIT  FIT  FIT
5 Something something UNH  UNA <NA>
6         I got into UCLA UCLA UCLA
7                Hello XT   CA   CA

【问题讨论】:

    标签: r string text-extraction


    【解决方案1】:

    您可以将列表转换为正则表达式,然后应用 R 正则表达式函数:

    expr <- paste0(list,collapse = "|")
    # expr = "NYU|FIT|UCLA|CA|UT|USC" -> Reg expr means NYU or FIT or ......
    
    data[,"C"] <- ""
    cols <- rev(names(data)[-(which(names(data)=="C"))])
    
    for(c in cols) {
     index <- regexpr(expr,data[,c])
     data[,"C"] <- ifelse(index != -1,substr(data[,c],index,index + attr(index,"match.length")-1),data[,"C"])     
    }
    

    希望对你有帮助

    哥达维亚诺尼

    【讨论】:

    • 这很棒。非常感谢!!你能告诉我 ifelse 函数内部发生了什么吗?这将非常有帮助
    • Ifelse 函数允许您在列表/df 列上使用 if 条件(if/then/else,不使用 boucle)。
    【解决方案2】:

    另一种方法可能是

    #common between column A & vector l
    C_tempA <- sapply(df$A, function(x) intersect(strsplit(as.character(x), split = " ")[[1]], l))
    #common between column B & vector l
    C_tempB <- sapply(df$B, function(x) intersect(as.character(x), l))
    
    #column C calculation
    df$C <- ifelse(C_tempA=="character(0)", C_tempB, C_tempA)
    df$C[df$C=="character(0)"] <- NA
    
    #final dataframe
    df
    

    输出是:

                            A    B    C
    1       This contains NYU  NYU  NYU
    2            This has NYU   UT  NYU
    3             This has XT  USC  USC
    4            This has FIT  FIT  FIT
    5 Something something UNH  UNA   NA
    6         I got into UCLA UCLA UCLA
    7                Hello XT   CA   CA
    

    样本数据:

    df <- structure(list(A = structure(c(4L, 6L, 7L, 5L, 3L, 2L, 1L), .Label = c("Hello XT", 
    "I got into UCLA", "Something something UNH", "This contains NYU", 
    "This has FIT", "This has NYU", "This has XT"), class = "factor"), 
        B = structure(c(3L, 7L, 6L, 2L, 5L, 4L, 1L), .Label = c("CA", 
        "FIT", "NYU", "UCLA", "UNA", "USC", "UT"), class = "factor")), .Names = c("A", 
    "B"), row.names = c(NA, -7L), class = "data.frame")
    
    l <- c("NYU","FIT","UCLA","CA","UT","USC")
    

    【讨论】:

      【解决方案3】:

      使用标记器包中的库(标记器)。

      合并两列并用合并的 A 和 B 创建一个新列

      data$newC <- paste(data$A, data$B, sep = " " )
      

      然后,按照下面的循环,将提取向量中的值,然后你可以在现有数据帧中绑定向量。

      newcolumn <- 'X'
      
      for (p in data$newC)
      {
        if (!is.na(p))
      {
      
      x <- which(is.element(unlist(tokenize_words(list, lowercase = TRUE)), unlist(tokenize_words(p, lowercase = TRUE, stopwords = NULL, simplify = FALSE))))
      
          newcolumn <- append(newcolumn,ifelse(x[1]!= 0, list[x[1]], "NA"))
        } 
      }
      
      newcolumn <- newcolumn[-1]
      
      newcolumn
      
      data <- cbind(data, newcolumn)
      

      希望对您有所帮助。 如您所料,我得到了上面的输出。

      解决方案图片:

      【讨论】:

        猜你喜欢
        • 2021-06-04
        • 2021-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-07
        • 2023-03-16
        • 1970-01-01
        • 2020-12-14
        相关资源
        最近更新 更多