Get (1, 2, 3, 4, 2, 3, 4, 3, 4, 4) from (1, 2, 3, 4) in R

Viewed 87

I have vector

z1 <- c(1, 2, 3, 4) 

and want to get from it another vector

z2 <- c(1, 2, 3, 4,
           2, 3, 4,
              3, 4,
                 4)

I've tried different variants of rep() function, but get only this

z3 <- rep(z1, times=seq(length(z1), 1))

z3 <- c(1, 1, 1, 1,
           2, 2, 2, 
              3, 3,
                 4)

Also z2 get be done with for() loops

temp <- z1
res <- c()

for (i in 1:length(z1)){
    
    res <- c(res, temp)
    temp <- temp[-1]
    
}

res <- c(1, 2, 3, 4,
            2, 3, 4,
               3, 4,
                  4)

But is there any ways to transform z1 to z2 with one string built-in functions like rep()?

4 Answers

You can try sapply + unlist + tail like below

> unlist(sapply(-seq_along(z1), tail, x = c(NA, z1)))
 [1] 1 2 3 4 2 3 4 3 4 4
c(z1, unlist(lapply(1:length(z1), function(x) z1[-c(1:x)])))
[1] 1 2 3 4 2 3 4 3 4 4

Edit: updating post to account for an ordered solution

Populate a matrix by repeating every value the maximum number of times. Then take the lower triangle of the matrix. Note: using length(z1) in this case so that the values are note required to be integers, use max(z1) instead if that value would make sense.

z2 <- matrix(data = rep(z1, times = length(z1)), ncol = length(z1), byrow = FALSE)
z2

Resulting matrix

     [,1] [,2] [,3] [,4]
[1,]    1    1    1    1
[2,]    2    2    2    2
[3,]    3    3    3    3
[4,]    4    4    4    4

Subset the matrix using lower.tri to extract the lower triangle and the diagonal

z2 <- z2[lower.tri(z2, diag = TRUE)]
print(z2)

Result

[1] 1 2 3 4 2 3 4 3 4 4

Previous partial solution (for an unordered solution)

Use lapply to iterate through the vector, with each iteration, repeat each element the desired number of times using rep, and then unlist the result to turn it into a vector

 z1 <- c(1, 2, 3, 4) 
 z2 <- unlist(lapply(z1, function(x) rep(x, times = x)))
 print(z2)

Result

 [1] 1 2 2 3 3 3 4 4 4 4

Base R using eval parse:

z1 <- c(1, 2, 3, 4) 
max_num <- max(z1)
unlist(lapply(paste(z1, max_num, sep = ":"), function(x){
      eval(parse(text=x))
    }
  )
)
Related