Подход с использованием математики, преимущество в том, что результаты возвращаются в виде чисел, и он быстрее.
Данные
df <- structure(list(id = 1:3, subscriberid = c(1234567890, 3243245324, 4532453245),
intName = c("asdfsadf", "dfsafdf", "dasdfsd")),
row.names = c(NA, 3L), class = "data.frame")
subid <- c(1234567890,2345345234)
Метод
idx <- df$subscriberid %in% subid
vals <- df[ idx, "subscriberid" ]
digits <- floor( log10( vals ) )
## number of digits given by `floor( log10( vals) ) + 1`, but we want the first digit
( ( vals / 10^digits ) + 9 - floor( vals / 10^digits ) ) * (10^digits)
# [1] 9234567890
Что этоделает поиск индексов data.frame, которые соответствуют subid
Затем
- вычисляет, сколько цифр в этих числах, используя
log10
- деление на 10 на степень этих цифр и сложение для получения первого целого числа
- вычитание этого целого числа из 9 (ваша цель)
- добавление его обратно в log10'dзначение
- умножение обратно на 10 до степени этих цифр, чтобы получить исходное количество цифр обратно
Контрольный показатель
library(microbenchmark)
microbenchmark(
ronak = { ronak( df, subid ) },
tim = { tim( df, subid ) },
tmfmnk = { tmfmnk( df, subid ) },
symbolix = { symbolix( df, subid ) },
times = 5
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# ronak 186.143804 188.618750 214.151592 191.154106 196.399341 308.4420 5
# tim 442.385985 463.510154 526.814255 506.268620 541.829769 680.0767 5
# tmfmnk 236.423472 255.418334 295.652617 295.624544 329.901976 360.8948 5
# symbolix 5.510366 5.828804 8.166222 5.850937 5.942607 17.6984 5
И показать результатыравны
res_ronak <- ronak( df, subid )
res_tim <- tim( df, subid )
res_tmfmnk <- tmfmnk( df, subid )
res_symbolix <- symbolix( df, subid )
all.equal(res_ronak, res_tim)
# [1] TRUE
all.equal(res_tim, res_tmfmnk)
# [1] TRUE
res_symbolix$subscriberid <- as.character(res_symbolix$subscriberid)
all.equal(res_tmfmnk, res_symbolix)
# [1] TRUE
Данные бенчмаркинга
set.seed(1234)
df <- data.frame(
subscriberid = sample(1:100000000, size = 1e5)
)
subid <- sample( df$subscriberid, size = 10 )
Функции бенчмаркинга
ronak <- function(df, subid) {
df$subscriberid <- with(df, ifelse(subscriberid %in% subid,
paste0("9",substring(subscriberid,2)), subscriberid))
return(df)
}
tim <- function(df, subid) {
regex <- paste0("\\b(", paste(subid, collapse="|"), ")\\b")
df$subscriberid <- ifelse(grepl(regex, df$subscriberid),
paste0("9", substr(df$subscriberid, 2, nchar(df$subscriberid))),
df$subscriberid)
return(df)
}
tmfmnk <- function(df, subid) {
df$subscriberid <- ifelse(df$subscriberid %in% subid,
sub(".", "9", df$subscriberid), df$subscriberid)
return(df)
}
symbolix <- function(df, subid) {
idx <- df$subscriberid %in% subid
vals <- df[ idx, "subscriberid" ]
digits <- floor( log10( vals ) )
df[ idx, "subscriberid" ] <- ( ( vals / 10^digits ) + 9 - floor( vals / 10^digits ) ) * (10^digits)
return(df)
}