Replicating specific values ​​in a vector defined by another vector

I have a vector of values ​​(say 1:10

) and want to repeat certain values ​​in it 2 or more times, defined by another vector (say c(3,4,6,8)

). In this example, the result will be c(1,2,3,3,4,4,5,6,6,7,8,8,9,10)

when repeated 2 times.

This should work for an arbitrary length-of-length vector (e.g. 200:600

), with the second vector contained first. Is there a convenient way to achieve this?

+3


source to share


4 answers


Akrun is a more compact method, but this will also work

# get rep vector
reps <- rep(1L, 10L)
reps[c(3,4,6,8)] <- 2L

rep(1:10, reps)
 [1]  1  2  3  3  4  4  5  6  6  7  8  8  9 10

      

The understanding here is that it rep

will accept an integer vector in the second argument of the same length as the first argument, which indicates the number of times to repeat for each element of the first argument.

Note that this decision is based on the assumption of what c(3,4,6,8)

is the index or position of the items to be repeated. In this case, db comment has a one-line

rep(x, (seq_along(x) %in% c(3,4,6,8)) + 1)

      

If instead c(3,4,6,8)

specifies values ​​to be repeated, then docendo-discimus is a super compact code,



rep(x, (x %in% c(3,4,6,8)) * (n-1) +1)

      

where n can be adjusted to change the number of repetitions. If you need to call this a couple of times it can be folded into a function like

myReps <- function(x, y, n) rep(x, (x %in% y) * (n-1) +1)

      

and called

myReps(1:10, c(3,4,6,8), 2)

      

in the current scenario.

+6


source


We can try

i1 <- v1 %in% v2
sort(c(v1[!i1], rep(v1[i1], each = 2)))
#[1]  1  2  3  3  4  4  5  6  6  7  8  8  9 10

      

Update



For an arbitrary vector

f1 <- function(vec1, vec2, n){
i1 <- vec1 %in% vec2
vec3 <- seq_along(vec1)
 c(vec1[!i1], rep(vec1[i1], each = n))[order(c(vec3[!i1], 
            rep(vec3[i1], each=n)))]
 }

set.seed(24)
v1N <- sample(10)
v2 <- c(3,4,6,8)
v1N
#[1]  3 10  6  4  7  5  2  9  8  1

f1(v1N, v2, 2)
#[1]  3  3 10  6  6  4  4  7  5  2  9  8  8  1
f1(v1N, v2, 3)
#[1]  3  3  3 10  6  6  6  4  4  4  7  5  2  9  8  8  8  1

      

+4


source


Here's a different approach using sapply

#DATA
x = 1:10
r = c(3,4,6,8)
n = 2 #Two repetitions of selected values

#Assuming 'r' is the index of values in x to be repeated
unlist(sapply(seq_along(x), function(i) if(i %in% r){rep(x[i], n)}else{rep(x[i],1)}))
#[1]  1  2  3  3  4  4  5  6  6  7  8  8  9 10

#Assuming 'r' is the values in 'x' to be repeated
unlist(sapply(x, function(i) if(i %in% r){rep(i, n)}else{rep(i, 1)}))
#[1]  1  2  3  3  4  4  5  6  6  7  8  8  9 10

      

Didn't test these thoroughly but there might be alternatives. Note that the order of output will vary significantly with this approach.

sort(c(x, rep(x[x %in% r], n-1))) #assuming 'r' is values
#[1]  1  2  3  3  4  4  5  6  6  7  8  8  9 10
sort(c(x, rep(x[r], n-1))) #assuming 'r' is index
#[1]  1  2  3  3  4  4  5  6  6  7  8  8  9 10

      

+3


source


I suggest this solution to just highlight the cool use of the function append

in R base:

ff <- function(vec, v, n) {
    for(i in seq_along(v)) vec <- append(vec, rep(v[i], n-1), after = which(vec==v[i]))
    vec
}

      

Examples:

set.seed(1)

ff(vec = sample(10), v = c(3,4,6,8), n = 2)
#[1]  3  3  4  4  5  7  2  8  8  9  6  6 10  1

ff(vec = sample(10), v = c(2,5,9), n = 4)
#[1]  3  2  2  2  2  6 10  5  5  5  5  7  8  4  1  9  9  9  9

      

+1


source







All Articles