【问题标题】:Extract distinct characters that differ between two strings提取两个字符串之间不同的不同字符
【发布时间】:2016-03-23 06:52:56
【问题描述】:

我有两个字符串,a <- "AERRRTX"; b <- "TRRA"

我想提取a中没有在b中使用的字符,即“ERX”

我在Extract characters that differ between two strings 中尝试了答案,它使用setdiff。它返回“EX”,因为b 确实有“R”,而setdiff 将消除a 中的所有三个“R”。我的目标是区分每个字符,因此a 中的三个 R 中只有两个应该被删除。

关于我可以使用什么来代替 setdiff 或其他一些方法来实现我的输出有什么建议吗?

【问题讨论】:

    标签: r string


    【解决方案1】:

    使用pmatch 的不同方法,

    a1 <- unlist(strsplit(a, ""))
    b1 <- unlist(strsplit(b, "")) 
    
    a1[!1:length(a1) %in% pmatch(b1, a1)]
    
     #[1] "E" "R" "X"
    

    另一个例子,

    a <- "Ronak";b<-"Shah"
    
    a1 <- unlist(strsplit(a, ""))
    b1 <- unlist(strsplit(b, ""))
    a1[!1:length(a1) %in% pmatch(b1, a1)]
    
    # [1] "R" "o" "n" "k"
    

    【讨论】:

    • 次要:建议避免分配c,因为它是常用的内置函数。如果c 是在任何封闭环境中定义的变量,则对该标识符的引用可以绑定到它,这会弄乱很多代码。例如,do.call(c,...) 在这种情况下会失败。
    • 不错的选择。您可以将第三行替换为 a1[-pmatch(b1, a1)]。此外,注意pmatch 的“duplicates.ok = FALSE”参数将其行为与match 区分开来会很有用
    【解决方案2】:

    您可以使用 vecsets 包中的函数 vsetdiff

    install.packages("vecsets")
    library(vecsets)
    a <- "AERRRTX"
    b <- "TRRA"  
    Reduce(vsetdiff, strsplit(c(a, b), split = ""))
    ## [1] "E" "R" "X"
    

    【讨论】:

      【解决方案3】:

      我们可以使用Reduce()依次从a中删除b中的每个字符:

      a <- 'AERRRTX'; b <- 'TRRA';
      paste(collapse='',Reduce(function(as,bc) as[-match(bc,as,nomatch=length(as)+1L)],strsplit(b,'')[[1L]],strsplit(a,'')[[1L]]));
      ## [1] "ERX"
      

      这将保留a 中幸存字符的顺序。


      另一种方法是用a中的每个字符的出现索引标记每个字符,对b做同样的事情,然后我们可以使用setdiff()

      a <- 'AERRRTX'; b <- 'TRRA';
      pasteOccurrence <- function(x) ave(x,x,FUN=function(x) paste0(x,seq_along(x)));
      paste(collapse='',substr(setdiff(pasteOccurrence(strsplit(a,'')[[1L]]),pasteOccurrence(strsplit(b,'')[[1L]])),1L,1L));
      ## [1] "ERX"
      

      【讨论】:

        【解决方案4】:

        使用data.table 包的替代方案:

        library(data.table)
        
        x = data.table(table(strsplit(a, '')[[1]]))
        y = data.table(table(strsplit(b, '')[[1]]))
        
        dt = y[x, on='V1'][,N:=ifelse(is.na(N),0,N)][N!=i.N,res:=i.N-N][res>0]
        
        rep(dt$V1, dt$res)
        #[1] "E" "R" "X"
        

        【讨论】:

          猜你喜欢
          • 2015-05-04
          • 2015-05-05
          • 1970-01-01
          • 1970-01-01
          • 2018-05-11
          • 1970-01-01
          • 2014-05-20
          • 2016-10-27
          • 1970-01-01
          相关资源
          最近更新 更多