Basically I want to generate a sequence, say:
n is 2, the sequence will be 112
n is 3, sequence is 112123
n is 5, sequence is 112123123412345
I did come up with a solution
n=5
seq=1
for (i in 2:n){
seq=c(seq,rep(1:n,len=i))
}
I am wondering if there is a way can do it without for loop?
Use sequence:
> sequence(1:5)
[1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
Here is one possibility:
n<-5
unlist(lapply(1:n,function(x) 1:x))
## [1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
It'd do something like:
do.call('c', sapply(1:5, seq, from = 1))
# [1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
I misread the question as "how to generate that annoying puzzler sequence," which goes
1,11,21,1112,3112,... :-). So I figured I might as well write a solution to that.
puzseq<-function(seqlen) {
theseq<- list(1)
for( j in 2:seqlen) {
thetab<-table(theseq[[j-1]])
theseq[[j]]<-unlist( sapply( 1:length(thetab), function(k) c(thetab[k], as.numeric(names(thetab)[k])) ))
}
return(theseq)
}
Related
I am aware of seq, which used in this way:
seq(by=1, to=3, by=1)
will get you from c(1) to
c(1,2,3)
How can I vectorize this behavior to go from
Input:
c(1,1,1)
Output:
c(1,1,1,2,2,2,3,3,3)
seq isn't vectorised. You could use one of the loops to get the same behavior.
For example, with mapply
x <- c(1,1,1)
c(t(mapply(seq, x, 3)))
#[1] 1 1 1 2 2 2 3 3 3
If you want every sequence go till length(x) use that instead of hard-coded 3.
Besides, if your x will always start with 1 as shown in the example you can use rep and sequence
sort(sequence(rep(length(x), length(x))))
#[1] 1 1 1 2 2 2 3 3 3
An option is rep and it is vectorized. No need to use loops
rep(seq_along(v1), each = length(v1))
#[1] 1 1 1 2 2 2 3 3 3
Or another option is replicate
c(t(replicate(3, seq(1, 3, 1))))
#[1] 1 1 1 2 2 2 3 3 3
If we wanted to vectorize the seq, use Vectorize
c(t(Vectorize(function(x) seq(x, 3, 1))(v1)))
#[1] 1 1 1 2 2 2 3 3 3
data
v1 <- c(1, 1, 1)
I'd like to produce a vector with the following repeating pattern:
1 1 2 1 2 3 1 2 3 4 ...
that ranges from one to some arbitrary stopping point.
I can hack it together using an sapply followed by an unlist, as in the following, but it sure feels like there should be a base call that is more direct than this.
repeating_function <- function(stop_point) {
res_list <- sapply(1:stop_point, FUN=function(x) {1:x}, simplify=TRUE)
res <- unlist(res_list)
return(res)
}
Which produces:
repeating_function(5)
[1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
An easier option would be
sequence(sequence(5))
#[1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
Wrapping in a function
repeating_function(val) {
sequence(sequence(val))
}
I'd think this would be simple using the rev() and seq() functions, but am struggling to get the reverse order part correct.
I'm trying to get 5432101234543210 from 5:0.
Not too hard to set as a function...
try_it <- function(x) {
c(rev(x), x[2:length(x-1)], rev(x)[2:length(x-1)])
}
try_it(0:5)
# [1] 5 4 3 2 1 0 1 2 3 4 5 4 3 2 1 0
Edit
Extend function to have variable repeats
try_it <- function(x, reps) {
c(rev(x), rep(c(x[2:length(x-1)], rev(x)[2:length(x-1)]), (reps - 1) / 2))
}
try_it(0:5, 5)
# [1] 5 4 3 2 1 0 1 2 3 4 5 4 3 2 1 0 1 2 3 4 5 4 3 2 1 0
Note: I've not worked hard to generalise this extension, it will not return the correct length for an even number of repetitions. I'm sure you could modify to suit your requirements.
I have a list that looks like this:
n <- c(1, rep(NA, 9), 2, rep(NA, 9))
I want the 9 observations following the first observation to contain the same value as the first observation. And continue this pattern throughout the whole list. So ideally, I want my list to look like this:
c(rep(1, 10), rep(2, 10))
I want to accomplish this without using for loops, is there a way to do this?
library(zoo)
na.locf(n)
##[1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
You can use the each argument in the rep command:
rep(1:2, each = 10)
# [1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
My favorite non-na.locf way:
c(NA, n[!is.na(n)])[cumsum(!is.na(n)) + 1]
# [1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
If there are NAs before the first value, they will stay. But if you know there are no NAs at the beginning of the vector it's just:
not.na <- !is.na(n)
n[not.na][cumsum(not.na)]
Basically I want to generate a sequence, say:
n is 2, the sequence will be 112
n is 3, sequence is 112123
n is 5, sequence is 112123123412345
I did come up with a solution
n=5
seq=1
for (i in 2:n){
seq=c(seq,rep(1:n,len=i))
}
I am wondering if there is a way can do it without for loop?
Use sequence:
> sequence(1:5)
[1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
Here is one possibility:
n<-5
unlist(lapply(1:n,function(x) 1:x))
## [1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
It'd do something like:
do.call('c', sapply(1:5, seq, from = 1))
# [1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
I misread the question as "how to generate that annoying puzzler sequence," which goes
1,11,21,1112,3112,... :-). So I figured I might as well write a solution to that.
puzseq<-function(seqlen) {
theseq<- list(1)
for( j in 2:seqlen) {
thetab<-table(theseq[[j-1]])
theseq[[j]]<-unlist( sapply( 1:length(thetab), function(k) c(thetab[k], as.numeric(names(thetab)[k])) ))
}
return(theseq)
}