Как устранить неоднозначность повторяющихся строк, добавляя строки различной длины? - PullRequest
2 голосов
/ 12 апреля 2019

Я видел умный код, представленный Габором Г. в ответ на этот вопрос о устранении неоднозначности строк.Его ответ, слегка модифицированный, таков:

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).) вхождение имени.(Код Габора вычисляет целое число и добавляет его, поэтому число добавляемых символов является постоянным).Лучшее, что я мог сделать, это следующая неуклюжая функция ("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 ]

2 голосов
/ 12 апреля 2019

Мы можем воспользоваться преимуществом 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 голос
/ 12 апреля 2019

Мы можем воспользоваться функцией 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') концептуально аналогично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...