Reputation: 68
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
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
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
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
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