Replicate certain values in vector determined by other vector

安稳与你 提交于 2020-01-04 04:01:21

问题


I have a vector of values (say 1:10), and want to repeat certain values in it 2 or more times, determined by another vector (say c(3,4,6,8)). In this example, the result would be c(1,2,3,3,4,4,5,6,6,7,8,8,9,10) when repeating 2 times.

This should work for an arbitrary length range vector (like 200:600), with a second vector which is contained by the first. Is there a handy way to achieve this?


回答1:


Akrun's is a more compact method, but this also will 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 insight here is that rep will take an integer vector in the second argument the same length as the first argument that indicates the number of repetitions for each element of the first argument.

Note that this solution relies on the assumption that c(3,4,6,8) is the index or position of the elements that are to be repeated. Under this scenario, then d-b's comment has a one-liner

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

If instead, c(3,4,6,8) indicates the values that are to be repeated, then docendo-discimus's super-compact code,

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

where n may be adjusted to change the number of repetitions. If you need to call this a couple times, this could be rolled up into a function like

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

and called as

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

in the current scenario.




回答2:


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 the 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



回答3:


Here's another 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

Haven't tested these thoroughly but could be possible alternatives. Note that the order of the output will be considerably different 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



回答4:


I suggest this solution just to emphasize the cool usage of append function in base R:

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


来源:https://stackoverflow.com/questions/43186235/replicate-certain-values-in-vector-determined-by-other-vector

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!