【问题标题】:Add a random value to a random block in vector将随机值添加到向量中的随机块
【发布时间】:2019-05-25 18:01:01
【问题描述】:

我有一个数字向量

vect <- c(0,16,11,132,0,0,0,18,28,245,0,0,55,45,19,30,20,0,0,0,12,0)

有四个系列的值不等于零。

(16,11,132), (18,28,245), (55,45,19,30,20), (12)

对于随机选择的 1/4 系列(一个系列),我想添加一个介于 -10 和 10 之间的随机整数值。

例如,如果选择的系列是第二个系列并且选择的值为 -5,则结果将是

vect2 <- c(0,16,11,132,0,0,0,13,23,240,0,0,55,45,19,30,20,0,0,0,12,0)

这是一个只有一行的例子,该函数将应用于整个矩阵

【问题讨论】:

  • 使用函数 rle.
  • 和两次调用sample(第一次选择要调整的分组,第二次确定随机整数值)。

标签: r vector random


【解决方案1】:

以下不是很优雅的代码,应该可以工作。它使用rle。

set.seed(1)
vect <- c(0,16,11,132,0,0,0,18,28,245,0,0,55,45,19,30,20,0,0,0,12,0)

# Get non-zero runs
runs <- rle(vect!=0)
non_zero_runs <- with(runs, lengths[values])

# Sample the required
rand_run <- sample(seq_along(non_zero_runs), size = 1)
print(rand_run)
#[1] 2
rand_int <- sample(-10:10, size = 1)
print(rand_int)
#[1] -3

# Identify the sampled run
which_run <- min(which(cumsum(runs$values) == rand_run))

# Identify the corresponding indices
start <- sum(runs$lengths[seq_len(which_run - 1)]) + 1
end <- start + runs$lengths[which_run] - 1

vect[start:end] <- vect[start:end] + rand_int
print(vect)
#[1]   0  16  11 132   0   0   0  15  25 242   0   0  55  45  19  30  20   0   0   0  12   0

您可以尝试自己减少代码。代码非常冗长,因为它是解决和理解问题的一部分。

【讨论】:

    【解决方案2】:

    这是一个长班轮:

    vect + with(rle(vect != 0), rep(replace(0 * values, which(values)[sample(sum(values), 1)], sample(-10:10, 1)), lengths))
    # [1]   0  16  11 132   0   0   0  18  28 245   0   0  55  45  19  30  20   0   0   0   8   0
    

    更详细的

    tmp <- rle(vect != 0)
    add <- sample(-10:10, 1)
    tmp$values <- replace(0 * tmp$val, which(tmp$val)[sample(sum(tmp$val), 1)], add)
    vect + inverse.rle(tmp)
    

    因此,我们通过将第二个分量添加到初始 vect 来构造一个新向量。部分

    replace(0 * tmp$val, which(tmp$val)[sample(sum(tmp$val), 1)], add)
    # [1] 0 3 0 0 0 0 0 0 0
    

    选择其中一个非零块并在其中放置一个新的随机值add。那么

    inverse.rle(tmp)
    # [1] 0 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    

    【讨论】:

      【解决方案3】:

      不使用rle 的解决方案。这里我使用diff 来查找不是0 的位置。然后随机选择一个位置并生成除该位置外的零向量。

      # Extract positions that are not 0
      sequences <- c(0, diff(vect != 0))
      
      # Get starts
      starts <- which(sequences == 1)
      # One random position from starts
      position <- sample(seq_along(starts), 1)
      
      # Get absolute start and end positions
      currentStart <- starts[position]
      currentEnd <- which(sequences == -1)[position] - 1
      
      # Add this vector to originak
      addVector <- rep(0, length(vect))
      addVector[currentStart:currentEnd] <- rep(sample(-10:10, 1), currentEnd - currentStart + 1)
      
      vect + addVector
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-06
        • 1970-01-01
        • 1970-01-01
        • 2015-10-01
        • 2012-10-26
        • 1970-01-01
        相关资源
        最近更新 更多