2015-04-03 65 views
3

给定两个等长的独立向量:f.start和f.end,我想从f.start [1]开始构造一个序列(由1) :f.end [1]到f.start [2]:f.end [2] ...到f.start [n]:f.end [n]。使用seq内的应用在R中创建索引向量

这是一个只有6行的例子。

f.start f.end 
[1,] 45739 122538 
[2,] 125469 202268 
[3,] 203563 280362 
[4,] 281657 358456 
[5,] 359751 436550 
[6,] 437845 514644 

粗略地说,一个循环可以做到这一点,但对于较大的数据集(行> 2000)极其缓慢。

f.start<-c(45739,125469,203563,281657,359751,437845) 
f.end<-c(122538,202268,280362,358456,436550,514644) 
f.ind<-f.start[1]:f.end[1] 
for (i in 2:length(f.start)) 
{ 
f.ind.temp<-f.start[i]:f.end[i] 
f.ind<-c(f.ind,f.ind.temp) 
} 

我怀疑这可以与应用()来实现,但我还没有制定出如何将两个单独的论点申请,并希望得到一些指导。

回答

4

您可以尝试使用mapplyMap,它们在您的两个向量上同时迭代。您需要提供该功能的第一个参数:

vec1 = c(1,33,50) 
vec2 = c(10,34,56) 

unlist(Map(':',vec1, vec2)) 
# [1] 1 2 3 4 5 6 7 8 9 10 33 34 50 51 52 53 54 55 56 

通过f.startf.end只需更换vec1vec2提供all(f.start<=f.end)

2

你的循环会因为你的成长矢量 f.ind缓慢。如果您预先分配输出向量的长度,您还将获得速度增加。

# Some data (of length 3000) 
set.seed(1) 
f.start <- sample(1:10000, 3000) 
f.end <- f.start + sample(1:200, 3000, TRUE) 

# Functions 
op <- function(L=1) { 
     f.ind <- vector("list", L) 
      for (i in 1:length(f.start)) { 
       f.ind[[i]] <- f.start[i]:f.end[i] 
      } 
     unlist(f.ind) 
     } 

op2 <- function() unlist(lapply(seq(f.start), function(x) f.start[x]:f.end[x])) 
col <- function() unlist(mapply(':',f.start, f.end)) 

# check output 
all.equal(op(), op2()) 
all.equal(op(), col()) 

几个基准

library(microbenchmark) 

# Look at the effect of pre-allocating 
microbenchmark(op(L=1), op(L=1000), op(L=3000), times=500) 
#Unit: milliseconds 
#   expr  min  lq  mean median  uq  max neval cld 
# op(L = 1) 46.760416 48.741080 52.29038 49.636864 50.661506 113.08303 500 c 
# op(L = 1000) 41.644123 43.965891 46.20380 44.633016 45.739895 94.88560 500 b 
# op(L = 3000) 7.629882 8.098691 10.10698 8.338387 9.963558 60.74152 500 a 

# Compare methods - the loop actually performs okay 
# I left the original loop out 
microbenchmark(op(L=3000), op2(), col(), times=500) 
#Unit: milliseconds 
#  expr  min  lq  mean median  uq  max neval cld 
# op(L = 3000) 7.778643 8.123136 10.119464 8.367720 11.402463 62.35632 500 b 
#  op2() 6.461926 6.762977 8.619154 6.995233 10.028825 57.55236 500 a 
#  col() 6.656154 6.910272 8.735241 7.137500 9.935935 58.37279 500 a 

所以循环应当履行好速度明智的,但当然上校的代码变得更干净。这里的*apply函数在计算中不会真的提高速度,但它们确实提供了更加整洁的代码,并且不需要预先分配。