如何通过附加不同长度的字符串来消除重复的字符串的歧义?

时间:2019-04-12 11:50:49

标签: r

我看到Gabor G.针对this question提交的有关字符串歧义消除的巧妙代码。他的回答(稍作修改)是:

uniqName <- function(x){
thenames <- ave(x,x,FUN = function(z){
    znam <- if (length(z) == 1) z else sprintf("%s%02d", z, seq_along(z))
    return(znam)
})
return(thenames)
}

我想去一个“不可见的”版本,并试图提出一个紧凑的函数,该函数将N个空格附加到名称的第(N + 1)个出现位置。 (Gabor的代码会计算一个整数并将其附加,因此附加的字符数是恒定的)。我能做的最好的就是以下笨拙的函数(“ fatit”)

spacify <- function (x){
    fatit <-function(x){
         k = vector(length=length(x))
         for(jp in 1:length(x)){
            k[jp]=sprintf('%s%s',x[jp],paste0(rep(' ',jp),collapse=''))
         }
         return(k)
     }
     spaceOut <- ave(x,x, FUN = function(z) if (length(z) == 1) z else fatit(z) )
     return(spaceOut)
    }

是否有一些更简洁,更紧凑的方法来基于length(z)函数中的fatit设置要附加的字符数?

注意:

uniqName(foo)
[1] "a01" "b01" "c01" "a02" "b02" "a03" "c02" "d"   "e" 

spacify(foo)
[1] "a "   "b "   "c "   "a  "  "b  "  "a   " "c  "  "d"    "e" 

2 个答案:

答案 0 :(得分:2)

我们可以利用make.unique的优势,方法是去除使字符唯一的数字,并使用(... + 1)作为要添加的字符数的参考,即

i1 <- as.numeric(gsub('\\D+', '', make.unique(x)))
i1[is.na(i1)] <- 0 #because where there is no number it returns NA
paste0(x, sapply(i1 + 1, function(i) paste(rep(' ', each = i), collapse = '')))
#[1] "a "   "b "   "c "   "a  "  "b  "  "a   " "c  "  "d "   "e "

答案 1 :(得分:1)

我们可以利用stri_pad_right中的stringi函数:

library(stringi)
f <- function(x){
    ave(x, x, FUN = function(z){
        if(length(z) == 1) z else stri_pad_right(z, nchar(z[1]) + seq_along(z))
    })
}

x <- c('a', 'b', 'c', 'a', 'b', 'a', 'c', 'd', 'e')
f(x)
# [1] "a "   "b "   "c "   "a  "  "b  "  "a   " "c  "  "d"    "e" 

使用stringr::str_pad(..., side = 'right')在概念上是相似的。