TL; DR:我想通过左侧的给定字符将列表中的每个字符串完成为给定大小。我要它快。请参见下面的代码并举例
我有veeeeery的大字符串矢量,其中包含...以及任何东西,但最多(已知)个字符。我想通过将零保留为给定的大小(优于char的最大数量)来完成thoose字符串
假设:
c("yop",NA,"1234567","19","12AN","PLOP","5689777")
举例来说,我希望目标尺寸为10
[1] "0000000yop" NA "0001234567" "0000000019" "00000012AN" "000000PLOP" "0005689777"
结果,尽可能快。
我试图写自己的书,但是速度不是很快。您能帮我更快吗?我有数十亿的苏糖可以治疗。
这是我的实际代码:
library(purrr)
zero_left <- function(field,nb){
map2_chr(
map(abs(nb-nchar(field)),~ rep("0",.x)),
field,
~ paste0(c(.x,.y),collapse=""))
}
trial <- c("yop","1234567","19","12AN","PLOP","5689777")
zero_left(trial,10)
此代码甚至不处理NA情况...但是如果没有,它会起作用,但速度太慢。
答案 0 :(得分:5)
这依赖于一个外部程序包,但是它需要您zero_left()函数花费的时间的1/30:
reduce
编辑1:
Base-R解决方案可能不是只是这么快:
nb <- 10
stringr::str_pad(trial, width=nb, pad="0")
[1] "0000000yop" "0001234567" "0000000019" "00000012AN" "000000PLOP" "0005689777"
编辑2:
请记住,gsub(pattern = " ", replacement = "0", sprintf("%*s", nb, trial), fixed = TRUE)
只是stringr
函数的包装器,您可以通过直接使用stringi
获得另一个速度提升:
stringi
答案 1 :(得分:2)
如果您关心速度,则基R 可以比stringr
/ stringi
快:
library(microbenchmark)
microbenchmark(
stringr=stringr::str_pad(trial, width=nb, pad="0"),
stringi=stringi::stri_pad_left(trial, width = nb, pad = "0"),
base=paste(strrep("0", nb - nchar(trial)), trial, sep="")
)
# Unit: microseconds
# expr min lq mean median uq max neval
# stringr 21.292 22.747 24.87188 23.7070 24.4735 129.470 100
# stringi 10.473 12.359 13.15298 13.0180 13.5445 21.418 100
# base 7.848 9.392 10.83702 10.2035 10.8980 43.620 100
唯一的结果是NA
在这里变成了文字"NANA"
paste(strrep("0", nb - nchar(trial)), trial, sep="")
# [1] "0000000yop" "NANA" "0001234567" "0000000019" "00000012AN"
# [6] "000000PLOP" "0005689777"
所以解决方法是
microbenchmark(
stringr=stringr::str_pad(trial, width=nb, pad="0"),
stringi=stringi::stri_pad_left(trial, width = nb, pad = "0"),
base={v=paste(strrep("0", nb - nchar(trial)), trial, sep="");v[is.na(trial)]=NA;}
)
# Unit: microseconds
# expr min lq mean median uq max neval
# stringr 20.657 22.6440 23.99204 23.3870 24.6190 60.096 100
# stringi 10.980 12.1585 13.57061 13.0790 13.7800 64.135 100
# base 10.766 11.9185 13.69714 13.0665 13.8035 87.226 100
(在这种情况下,使基数R大约与stringi
一样快,而比stringr
快一点)。
(我很生气paste
将NA
转换为"NA"
,尽管那是already been addressed here on SO。)