MMWeb
MMWeb

Reputation: 68

How to generate a sequential character vector without a loop?

I'm trying to generate a character vector that includes a sequence of n numbers (as character) with m empty string elements in between each number element.

I managed to generate the vector using a loop. Is there a way to implement this more conciseley without a loop, and would this be more efficient?

sequence = character(0)
n = 3
m = 2

for(i in 1:n){
  sequence <- c(sequence, rep("",m), i)
  i <- i + 1
}

The output is a vector like:

c("","","1","","","2","","","3")

Upvotes: 2

Views: 205

Answers (4)

G. Grothendieck
G. Grothendieck

Reputation: 269624

1) Create an m by n matrix of "" and rbind 1:n to the bottom of it. Then unravel that into a vector:

c(rbind(matrix("", m, n), 1:n))
## [1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

2) Another approach is to create an m1*n long vector of "" and replace positions m1*(1:n) with 1:n.

m1 <- m + 1
replace(character(m1 * n), m1 * (1:n), 1:n)
## [1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

Alternately we could use a logical second argument:

replace(character(m1 * n), c(logical(m), TRUE), 1:n)
## [1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

Upvotes: 4

akrun
akrun

Reputation: 887118

1) We can use lapply to create the vector

unlist(lapply(1:3, function(x) c("", "", x)))
#[1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

2) Or with rep

replace(rep("", 9), c(FALSE, FALSE, TRUE), 1:3)
#[1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

3) Or using rep with seq

v1 <- rep("", 9)
v1[seq(3, length(v1), by = 3)] <- 1:3

4) Or using paste and strsplit

unlist(strsplit(sprintf("  %d", 1:3), " "))
#[1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

NO Packages used

Upvotes: 3

N. Williams
N. Williams

Reputation: 185

A succinct way:

library(purrr)

map2(1:3, 2, ~ c(rep("", .y), .x)) %>% unlist()
#> [1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

Created on 2019-06-18 by the reprex package (v0.3.0)

Upvotes: 0

www
www

Reputation: 39154

Here is another way to with rep and lapply.

seq_fun <- function(n, m){
  unlist(lapply(1:n, function(x) c(rep("", times = m), x)))
}

seq_fun(3, 2)
# [1] ""  ""  "1" ""  ""  "2" ""  ""  "3"

Upvotes: 5

Related Questions