使用mapply 的另一种解决方法:
c(1, unlist(mapply(function(s,e) tail(s:e,-1), head(c(1,x),-1), x)))
#[1] 1 2 3 4 5 4 3 2 1 2 3 4 5 6
或
c(seq(x[1]-1),
unlist(sapply(seq(length(x)-1), function(i) head(x[i]:x[i+1], -1))),
tail(x,1))
#[1] 1 2 3 4 5 4 3 2 1 2 3 4 5 6
基准测试(base R 解决方案)
library(microbenchmark)
set.seed(1)
x <- sample(1000, 500, replace = FALSE)
f_Frank <- function(x) Reduce(function(y, z) c(head(y,-1), tail(y,1):z), x, init=1L)
f_989_1 <- function(x) c(1, unlist(mapply(function(s,e) tail(s:e,-1), head(c(1,x),-1), x)))
f_989_2 <- function(x)
c(seq(x[1]-1),
unlist(sapply(seq(length(x)-1), function(i) head(x[i]:x[i+1], -1))),
tail(x,1))
f_akrun <- function(x){
v1 <- rle(unlist(Map(":", x[-length(x)], x[-1])))$values
c(seq(v1[1]), v1[-1])
}
r <- f_Frank(x)
all(r==f_989_1(x))
#[1] TRUE
all(r==f_989_2(x))
#[1] TRUE
all(r==f_akrun(x))
#[1] TRUE
res <- microbenchmark(f_Frank(x), f_989_1(x), f_989_2(x), f_akrun(x))
print(res, order="mean")
# Unit: milliseconds
# expr min lq mean median uq max neval
# f_989_1(x) 5.851345 6.113956 6.627022 6.308359 7.256490 9.286613 100
# f_989_2(x) 5.604960 5.794707 7.260833 5.946143 6.876246 58.284487 100
# f_akrun(x) 6.826068 7.726124 13.491295 8.263214 8.983740 63.384959 100
# f_Frank(x) 287.564706 340.390713 351.593511 344.465231 359.258399 454.095461 100