【问题标题】:Create a vector from another selecting some of its values at random but in order and with a minimum distance between selected ones?从另一个随机选择其一些值但按顺序且所选值之间的距离最小的向量创建一个向量?
【发布时间】:2021-05-08 05:29:32
【问题描述】:

我有一个数字向量,我想随机但按顺序选择其中一些。我该怎么办?

例如:

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

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

第二部分(更新)

如果我想在连续选定的值中包含一定数量的步数怎么办?

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

[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

如何从这 14 个值中选择 3 个值,附加条件是在两个选定值之间必须至少有 3 个未选定值。例如,选定的向量可以是2.1 5.4 6.8,但不能是1.6 5.4 10.8

【问题讨论】:

    标签: r vector random sequence


    【解决方案1】:

    试试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)
    }
    

    【讨论】:

    • 感谢@ThomaslsCoding。我忘了包括一个额外的条件来创建向量。我道歉。我刚刚包括了它。考虑到我不想选择彼此非常接近的值,您知道如何创建向量吗?
    【解决方案2】:

    我们可以从vectorsample 4 个元素,然后match 获取索引并子集vector

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

    如果我们需要sample 每4个元素,我们可以通过指定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)
    

    【讨论】:

    • 谢谢@akrun。正如我对 ThomaslsCoding 所说,我忘记包含一个额外的条件来创建向量。我道歉。我刚刚包括了它。考虑到我不想选择彼此非常接近的值,您知道如何创建向量吗?
    • @Dekike 如果采样的第一个元素在位置 12,你是丢弃还是倒退
    • 好问题。然后应该有另一个条件,即选择的第一个值距离开始不超过 3 个位置(例如)。你明白吗?我的真实案例是随着时间的推移动物的数据。由于数据中的时间自相关性很高,我想选择原始数据的一部分(这就是为什么我需要按顺序排列数据)。
    • @Dekike 您可以使用for 循环使其更加健壮
    • @Dekike 你可以查看getAnywhere("rollapply.zoo") which is called by "rollapply.default"`。它可能有一个指定“宽度”的条件。
    【解决方案3】:

    一种选择是使用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
    

    【讨论】:

    • 谢谢@jared_mamrot。正如我对其他很好地提出了解决方案的人所说的那样,我忘了包括一个额外的条件来创建向量。我道歉。我刚刚包括了它。考虑到我不想选择彼此非常接近的值,您知道如何创建向量吗?另外,我想问你是否可以解释一下函数createeDataPartition中的参数是什么意思。
    【解决方案4】:

    这就是你要找的吗?只需使用sort 函数即可整理。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-06
      • 2019-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      相关资源
      最近更新 更多