使用常量(自然数)展开数字向量元素

时间:2017-05-31 10:43:38

标签: r vector integer

如果向量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

4 个答案:

答案 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