Generate an incrementally increasing sequence like 112123123412345 - r

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

What is an expressive and efficient way to vectorize seq in R

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)

Patterned Vector in base

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 am trying to take a vector of numbers 5:0 and repeat it 3 times, every other time reversing its order

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.

How to fill a list based off of other items in the list in R?

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)]

Adding elements to vector with initial element as maximum [duplicate]

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)
}

Resources