Adding elements to vector with initial element as maximum [duplicate] - 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

Reorder (collate) vector elements automatically

It's an easy one, but I can find a simple solution for my problem. I have several vectors look like this one: rep(1:3, each = 3) and I want to convert them to like rep(1:3, times = 3).
So each element is repeated multiple times c(1,1,1,2,2,2,3,3,3) and I want to reorder them to c(1,2,3,1,2,3,1,2,3). How can I achieve that?
You can use a matrix transpose:
as.vector(t(matrix(x, nrow = 3)))
# [1] 1 2 3 1 2 3 1 2 3
v1 <- c(1,1,1,2,2,2,3,3,3)
o1 <- rle(v1)
rep(o1$values, min(o1$length))
[1] 1 2 3 1 2 3 1 2 3
This allows for unknown amount of numbers or strings but expects each value to be present in equal numbers. It only has some flexibility on what you want to do on some values occuring more than others.
Consider:
v2 <- c(1,1,1,2,2,2,3,3,3,3)
o2 <- rle(v2)
rep(o2$values, min(o2$length))
[1] 1 2 3 1 2 3 1 2 3
rep(o2$values, max(o2$length))
[1] 1 2 3 1 2 3 1 2 3 1 2 3

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.

Generate an incrementally increasing sequence like 112123123412345

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

Create vector of the culmative counts per level

I have lots of little vectors like this:
id<-c(2,2,5,2,1,9,4,4,3,9,5,5)
and I want to create another vector of the same length that has the cumulative number of occurrences of each id thus far. For the above example data this would look like:
> id.count
[1] 1 2 1 3 1 1 1 2 1 2 2 3
I can not find a function that does this easily, maybe because I do not really know how to fully articulate in words what it is that I actually want (hence the slightly awkward question title). Any suggestions?
Here is another way:
ave(id,id,FUN=seq_along)
Gives:
[1] 1 2 1 3 1 1 1 2 1 2 2 3
> sapply(1:length(id), function(i) sum(id[1:i] == id[i]))
[1] 1 2 1 3 1 1 1 2 1 2 2 3
Or if you have NAs in id you should use id[1:i] %in% id[i] instead.

Resources