Reputation: 1077
I want to create a vector composed by N pairs of real where each pairs are separated by a value S and the two elements of the pair are separate by a a value iS, that could be written like that:
V=[(X,X+iS)_1, (X+S+iS,X+S+2*iS)_2, ... ]
So if we start from X=1
, with S=1
and iS = .5
it should return:
V=[1.0,1.5,2.5,3.0,4.0,4.5]
I create this function that does exactly what i want:
myseq<-function(x,n,sep,isep){
res=c(x,x+isep)
for(i in 1:(n-1)){
prev=res[length(res)]
res=c(res,c(prev+sep,prev+sep+isep))
}
return(res)
}
With the same example than before:
> myseq(1,3,1,.5)
[1] 1.0 1.5 2.5 3.0 4.0 4.5
But I am sure it could be written in a simpler and more "functional" way, but I can't figure it out. If you have any Idea?
Upvotes: 3
Views: 707
Reputation: 1077
After reviewing my question I realized that my accepted answer was maybe not the best one and that @alexis_laz in his comment came up with a short and better solution. I put them here again, and after benchmarking it seems that
My original version:
original<-function(x,n,sep,isep){
res=c(x,x+isep)
for(i in 1:(n-1)){
prev=res[length(res)]
res=c(res,c(prev+sep,prev+sep+isep))
}
return(res)
}
The previously accepted answer:
accepted <- function(x,isep,sep,n){
c(rbind(seq(x,by = isep+sep, length.out = n), seq(x+isep,by = isep+sep, length.out = n)))
}
Alexis' comment:
alexcomm <- function(x,n,sep,isep){
cumsum(c(x, rep_len(c(isep, sep), (n * 2) - 1)))
}
And the benchmark:
expr min lq mean median
alexcomm(x, n, sep, isep) 99.657 105.0090 149.4527 109.1745
accepted(x, isep, sep, n) 130.090 137.7555 193.6189 163.2150
original(x, n, sep, isep) 251176.761 258936.2820 268247.7626 270124.8435
Thus the solution proposed in comment is not only the short but also slightly quicker.
Upvotes: 0
Reputation: 51592
Here is one idea using seq
,
myseq <- function(x, n, sep, isep) {
v1 <- seq(x, n*2, sep)[c(rep(TRUE, 2), rep(FALSE, (isep/sep)-1))]
return(v1[1:(n*2)])
}
myseq(1,3, 0.5, 1)
#[1] 1.0 1.5 2.5 3.0 4.0 4.5
Upvotes: 3
Reputation: 2076
Here is one more approach where you create 2 different vectors and then combine them alternatively in order to get the desired sequence.
myfun=function(i,x,y,n){
c(rbind(seq(i,by = x+y, length.out = n), seq(i+x,by = x+y, length.out = n)))
}
myfun(1,0.5,1,3)
[1] 1.0 1.5 2.5 3.0 4.0 4.5
Upvotes: 2