如果向量v <- c(1, 10, 22)
和常量自然数说c <- 3
,如何在大小为v
的窗口中使用整数展开c
。所以向量将变为w
(即1向每边扩展三个整数,整数-2,-1,0,1,2,3,4):
> w
[1] -2 -1 0 1 2 3 4 7 8 9 10 11 12 13 19 20 21 22 23 24 25
答案 0 :(得分:5)
另一种方法是
c(t(sapply(-c:c, `+`, v)))
#[1] -2 -1 0 1 2 3 4 7 8 9 10 11 12 13 19 20 21 22 23 24 25
这对于大型v向量更有效,因为sapply循环仅在-c:c
而不是v
的每个元素上进行迭代。一个简单的比较表明了这一点:
set.seed(1)
v <- sample(1e6)
system.time(unlist( Map(`:`, v-c, v+c))) # akrun 1
# User System verstrichen
# 1.518 0.067 1.595
system.time(c(sapply(v, function(x) (x-c):(x+c)))) # akrun 2
# User System verstrichen
# 1.564 0.074 1.652
system.time(c(t(sapply(-c:c, '+', v)))) # docendo
# User System verstrichen
# 0.082 0.024 0.106
system.time(c(mapply(seq, v-c, v+c))) # 989
# User System verstrichen
# 7.132 0.123 7.292
答案 1 :(得分:2)
我们可以使用sapply
c(sapply(v, function(x) (x-c):(x+c)))
#[1] -2 -1 0 1 2 3 4 7 8 9 10 11 12 13 19 20 21 22 23 24 25
或Map
unlist( Map(`:`, v-c, v+c))
答案 2 :(得分:2)
使用mapply
:
c(mapply(seq, v-c, v+c))
#[1] -2 -1 0 1 2 3 4 7 8 9 10 11 12 13 19 20 21 22 23 24 25
答案 3 :(得分:1)
这是另一个非常快的选择(虽然可能不是很优雅......):
w <- rep.int(v, rep(c*2+1,length(v))) + (-c:c)
基准:
library(microbenchmark)
set.seed(1)
v <- sample(1e6)
c <- 3
microbenchmark(times=30,
docendo =c(t(sapply(-c:c, '+', v))),
digemall=rep.int(v, rep(c*2+1,length(v))) + (-c:c)
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# docendo 81.04337 82.50133 100.7718 83.78972 99.89731 169.38202 30
# digemall 28.57355 30.28533 37.0091 31.01103 32.18491 90.90412 30
c <- 20
microbenchmark(times=30,
docendo =c(t(sapply(-c:c, '+', v))),
digemall=rep.int(v, rep(c*2+1,length(v))) + (-c:c)
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# docendo 581.9529 626.4765 673.2964 663.0599 713.8367 787.1848 30
# digemall 174.3748 177.2943 198.9419 180.0702 200.0904 319.6669 30