给定两个长度相等的独立向量:f.start和f.end,我想构建一个序列(乘以1),从f.start[1]:f.end[1]
到f.start[2]:f.end[2]
,...,到f.start[n]:f.end[n]
。
这是一个只有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)
}
我怀疑这可以通过apply()来完成,但是我还没有弄清楚如何在apply中包含两个单独的参数,并希望得到一些指导。
答案 0 :(得分:5)
您可以尝试使用mapply
或Map
,它会同时迭代您的两个向量。您需要提供函数作为第一个参数:
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
只需将vec1
和vec2
替换为f.start
,f.end
提供all(f.start<=f.end)
答案 1 :(得分: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
函数在计算中不会真正加快速度,但它们确实提供了更整洁的代码并且无需预先分配。