2015-04-03 76 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函數在計算中不會真的提高速度,但它們確實提供了更加整潔的代碼,並且不需要預先分配。