【问题标题】:apply regexp and update column across data frames跨数据框应用正则表达式和更新列
【发布时间】:2018-09-17 19:42:42
【问题描述】:

我有两个数据框 --- 表 A 是带有参考名称的模式表,表 B 是旧名称表。我想对表 B 进行子集化,它与表 a 中的模式匹配,当单元格匹配时,用 A 中的更新列更新 B 中的新列。

我引用了apply regexp in one data frame based on the column in another data frame,但它并不能解决这个问题。

A <- data.frame(pattern = c("ab", "be|eb", "cc", "dd"), 
                ref = c("first", "second", "third", "forth"))
B <- data.frame(name = c("aa1", "bb1", "cab", "ccaa" "abed" ,"ddd", "ebba"))
B$new = ""

我希望我的结果表是:

name       new
cab        first
abed       second
ccaa       third
ddd        forth
ebba       second

我在尝试

for (i in 1:nrow(B)) {
  if (as.data.table(unlist(lapply(A$pattern, grepl, B$name))) == TRUE) {
    B$new[i] = A$update
  }
}

有人知道更好的解决方案吗?我更喜欢使用 apply 系列,但我不知道如何添加列。任何帮助表示赞赏!

【问题讨论】:

    标签: r for-loop apply lapply


    【解决方案1】:

    我编辑了我的答案,因为我忘了先添加将 B 更改为矩阵的行:

    B <- as.matrix(B,ncol=1) 
    

    它现在应该可以正常工作了:

    library(reshape2)
    L <- apply(A, 1, function(x) B[grepl(x[1],B),])
    names(L) <- A$ref
    result <- melt(L)
    colnames(result) <- c('Name','New')
    
        result
    #  Name    New
    #1  cab  first
    #2 abed  first
    #3 abed second
    #4 ebba second
    #5 ccaa  third
    #6  ddd  forth
    

    【讨论】:

      【解决方案2】:

      您可以将stack 与 sapply 一起使用:

      stack(setNames(sapply(A$pattern,grep,B$name,value=T),A$ref))
      
        values    ind
      1    cab  first
      2   abed  first
      3   abed second
      4   ebba second
      5   ccaa  third
      6    ddd  forth
      

      你也可以使用stack(setNames(Vectorize(grep)(A$pattern,B[1],value=T),A$ref))

      【讨论】:

        【解决方案3】:
        # Your data
        A <- data.frame(pattern = c("ab", "be|eb", "cc", "dd"), 
                    ref = c("first", "second", "third", "fourth"), stringsAsFactors = F)
        B <- data.frame(name = c("aa1", "bb1", "cab", "ccaa", "abed" ,"ddd", "ebba"), stringsAsFactors = F)
        
        patternfind <- function(i){
          ifelse(grepl(A$pattern[[i]], B$name), A$ref[[i]], NA) 
        } # grepl function for your apply
        
        m = sapply(seq_along(A$pattern), patternfind) # apply function 
        
        test <- cbind(B,m) #bind your pattern matrix to B
        melt(test, id = c("name"), value.name = "new", na.rm = T) # melt data for output
        
           name variable    new
        3   cab        1  first
        5  abed        1  first
        12 abed        2 second
        14 ebba        2 second
        18 ccaa        3  third
        27  ddd        4  fourth
        

        如果您想走data.table 路线。

        library(data.table)
        
        DT.A <- as.data.table(A) # set as data tables
        DT.B <- as.data.table(B)
        
        ab <- DT.A[, DT.B[grep(pattern, name)], by=.(pattern, new = ref)] # use grep and by, leave out pattern if don't need to see what matched
        ab[,c(3,2,1)] # reorder to your desired order
        ab[,3:2] # subset to remove the pattern if you decide you don't want to display it
        
           name    new
        1:  cab  first
        2: abed  first
        3: abed second
        4: ebba second
        5: ccaa  third
        6:  ddd  fourth
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-04
          • 2021-03-23
          • 2021-04-10
          • 2019-10-19
          • 2020-07-03
          相关资源
          最近更新 更多