【问题标题】:Replicate certain values in vector determined by other vector复制由其他向量确定的向量中的某些值
【发布时间】:2017-04-03 13:42:22
【问题描述】:

我有一个值向量(例如 1:10),并且想要在其中重复某些值 2 次或更多次,由另一个向量(例如 c(3,4,6,8))确定。在此示例中,重复 2 次时结果将是 c(1,2,3,3,4,4,5,6,6,7,8,8,9,10)

这应该适用于任意长度范围的向量(如200:600),第二个向量包含在第一个向量中。有没有方便的方法来实现这一点?

【问题讨论】:

  • 可能比 1:10 让您的示例向量更随机,因为您希望它与任意向量一起使用
  • 是的,是的。我实际需要的示例也已排序,因此我将其添加到问题中。

标签: r vector double repeat replicate


【解决方案1】:

Akrun's 是一种更紧凑的方法,但也可以使用

# 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

这里的见解是rep 将在第二个参数中采用一个整数向量,其长度与第一个参数相同,表示第一个参数的每个元素的重复次数。

请注意,此解决方案依赖于c(3,4,6,8) 是要重复的元素的索引或位置的假设。在这种情况下,那么 d-b 的评论是单行的

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

如果相反,c(3,4,6,8) 表示要重复的值,那么 docendo-discimus 的超紧凑代码,

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

其中 n 可以调整以更改重复次数。如果您需要多次调用它,可以将其汇总到一个函数中,例如

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

并称为

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

在当前场景中。

【讨论】:

  • 这可以缩短为rep(x, (x %in% y) * (n-1) +1),假设x是初始向量,y是要重复的元素,n是重复次数,其中n&gt;1
  • 这也可能是一种变体:rep(x, (seq_along(x) %in% r) + 1),其中r = c(3,4,6,8)x = 1:10
  • @d.b,这是不正确的(或仅适用于 x = 1:10 的非常特殊的情况)。例如,尝试使用x = sample(1:10)x = 16:22:
  • @docendodiscimus,我(可能是错误的)假设r 是要重复的值的索引。但是如果r 不是索引,那么你可以只做rep(x, (x %in% r) + 1)
  • @d.b.,那么这将被限制为 2 次重复,但 OP 希望它被重复 2 次或更多次
【解决方案2】:

我们可以试试

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

更新

对于任意向量,

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】:

    这是使用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
    

    尚未彻底测试这些,但可能是可能的替代方案。请注意,这种方法的输出顺序会大不相同。

    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
    

    【讨论】:

    • 您的解决方案都不适用于任意向量。例如x&lt;-c(9L, 7L, 8L, 4L, 1L, 6L, 2L, 10L, 5L, 3L)r &lt;- c(3,4,6,8)n&lt;-2
    【解决方案4】:

    我建议这个解决方案只是为了强调append 函数在基础 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
    }
    

    例子:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-01
      • 2021-09-27
      • 2017-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多