从另一个向量创建一个向量,随机但按顺序选择它的一些值,并且所选值之间的距离最小?

Create a vector from another selecting some of its values at random but in order and with a minimum distance between selected ones?

我有一个数字向量,我想 select 随机但按顺序排列其中的一些。我该怎么做?

例如:

vector <- runif(10, min=0, max=101)
vector 

  [1] 35.956732 67.608039 20.099881 23.184217  9.157408 34.105185 97.459770 25.805254 74.537667 18.865662

我可以使用哪个代码来创建一个新向量,例如包含 10 个值中的四个值,并且要求这四个值的顺序与原始向量的顺序相同?即向量不能是9.157408 67.608039 74.537667 97.459770而是67.608039 9.157408 97.459770 74.537667.

任何帮助都会很棒。提前致谢。

第二部分(更新)

如果我想在连续的 selected 值中进行一定数量的步数怎么办?

也就是说,如果我有这个向量:

[1] 2.1 3.4 1.6 8.9 2.3 5.4 6.4 1.3 10.8 3.7 13.4 2.4 5.4 6.8

我如何才能 select 这 14 个值中的 3 个,附加条件是两个 selected 值之间必须至少有 3 个非 selected 值。例如,selected 向量可以是 2.1 5.4 6.8 但不能是 1.6 5.4 10.8.

这是您要找的吗?只需使用 sort 功能进行排序。

vector <- runif(10, min=0, max=101)
n <- 5
i <- sort(sample(seq_along(vector),n))
vector[i]

一种选择是使用 caret package 中的 createDataPartition() 函数,例如

library(caret)
vector <- runif(10, min=0, max=101)
vector
#>[1] 49.12759 37.39169 99.31837 39.22023 23.15373 62.95305 13.79056 97.71442
#>[9] 52.02225 16.47010

sampling_index <- createDataPartition(y = vector, times = 1,
                                      p = 0.3, list = FALSE)
vector[sampling_index]
#>[1] 49.12759 39.22023 23.15373 97.71442

尝试sample喜欢

vector[sort(sample(length(vector),4))]

vector[head(which(sample(c(TRUE,FALSE),length(vector),replace = TRUE)),4)]

更新

如果您对随机索引之间的最小间距有限制,可以尝试以下代码:

  • 非优化方法
f1 <- function(vec,n, min_spacing = 4) {
  idx <- seq_along(vec)
  repeat {
    k <- sort(sample(idx,n))
    if (all(diff(k)>=min_spacing)) break
  }
  vec[k]
}

  • 优化方法
f2 <- function(vec, n, min_spacing = 4) {
  u <- unname(tapply(vec, ceiling(seq_along(vec) / min_spacing), sample, size = 1))
  head(u[seq(1, length(u), by = 2)], n)
}

我们可以 sample 来自 vector 的 4 个元素,然后 match 得到索引和 vector

的子集
v1 <- sample(vector, 4)
vector[match(v1, vector)]

如果我们需要 sample 每 4 个元素 1 个,我们可以通过指定 widthby

使用 rollapply
library(zoo)
rollapply(v2, 4, by = 4, FUN = function(x) sample(x, 1))
#[1] 1.6 1.3 2.4

或者使用循环

out <- c()
flag <- TRUE
i <- 1
while(flag) {
    if((i + 4) > length(v2)) {
    break
      flag <- FALSE
      
    }
    
    i1 <- i:(i + 2)
    
    tmp <- sample(i1, 1)
    out <- c(out, tmp)

    i <- tmp + 3
    

}

out
#[1]  3  7 11

数据

v2 <- c(2.1, 3.4, 1.6, 8.9, 2.3, 5.4, 6.4, 1.3, 10.8, 3.7, 13.4, 2.4, 
5.4, 6.8)