考虑以下以逗号分隔的数字字符串:
s <- "1,2,3,4,8,9,14,15,16,19"
s
# [1] "1,2,3,4,8,9,14,15,16,19"
Run Code Online (Sandbox Code Playgroud)
是否可以将连续数字的运行折叠到其相应的范围内,例如1,2,3,4上面的运行将折叠到范围内1-4。所需的结果类似于以下字符串:
s
# [1] "1-4,8,9,14-16,19"
Run Code Online (Sandbox Code Playgroud)
我从这个问题的答案中得到了一些重要的启发。
findIntRuns <- function(run){
rundiff <- c(1, diff(run))
difflist <- split(run, cumsum(rundiff!=1))
unlist(lapply(difflist, function(x){
if(length(x) %in% 1:2) as.character(x) else paste0(x[1], "-", x[length(x)])
}), use.names=FALSE)
}
s <- "1,2,3,4,8,9,14,15,16,19"
s2 <- as.numeric(unlist(strsplit(s, ",")))
paste0(findIntRuns(s2), collapse=",")
[1] "1-4,8,9,14-16,19"
Run Code Online (Sandbox Code Playgroud)
Unit: microseconds
expr min lq median uq max neval
spee() 277.708 295.517 301.5540 311.5150 1612.207 1000
seb() 294.611 313.025 321.1750 332.6450 1709.103 1000
marc() 672.835 707.549 722.0375 744.5255 2154.942 1000
Run Code Online (Sandbox Code Playgroud)
@speendo 的解决方案目前是最快的,但这些都没有经过优化。