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