组合/求和 R 中整数向量中的两个位置

jps*_*ith 6 r vector

我在 R 中有一个简单的整数向量。我想在向量中随机选择n 个位置并在向量中“合并”它们(即总和)。此过程可能发生多次,即在 100 个向量中,可能会发生 5 个合并/求和事件,每个事件中分别合并 2、3、2、4 和 2 个向量位置。例如:

#An example original vector of length 10:
ex.have<-c(1,1,30,16,2,2,2,1,1,9)

#For simplicity assume some process randomly combines the 
#first two [1,1] and last three [1,1,9] positions in the vector. 

ex.want<-c(2,30,16,2,2,2,11)

#Here, there were two merging events of 2 and 3 vector positions, respectively

#EDIT: the merged positions do not need to be consecutive. 
#They could be randomly selected from any position. 
Run Code Online (Sandbox Code Playgroud)

但此外,我还需要记录“合并”了多少个向量位置(如果向量中的位置未合并,则包括值 1)——将它们称为索引。由于前两个合并后三个合并在上面的示例中,索引数据将如下所示:

ex.indices<-c(2,1,1,1,1,1,3)
Run Code Online (Sandbox Code Playgroud)

最后,我需要把它全部放在一个矩阵中,所以上面例子中的最终数据将是一个 2 列矩阵,其中一列是整数,另一列是索引:

ex.final<-matrix(c(2,30,16,2,2,2,11,2,1,1,1,1,1,3),ncol=2,nrow=7)
Run Code Online (Sandbox Code Playgroud)

目前我正在寻求帮助,即使是最简单的步骤:组合向量中的位置。我尝试了samplesplit函数的多种变体,但遇到了死胡同。例如,sum(sample(ex.have,2))将两个随机选择的位置相加(或sum(sample(ex.have,rpois(1,2))将在n值中添加一些随机性),但我不确定如何利用它来实现所需的数据集。详尽的搜索导致了多篇关于组合向量的文章,但不是向量中的位置,所以如果这是重复的,我深表歉意。任何关于如何处理这些问题的建议将不胜感激。

www*_*www 1

这是我设计的一个函数来执行您所描述的任务。

vec_merge函数采用以下参数:

x:整数向量。

event_perc:事件的百分比。这是 0 到 1 之间的数字(尽管 1 可能太大)。事件数的计算方式为 的长度x乘以event_perc

sample_n:合并样本数。这是一个整数向量,所有数字都大于或至少等于2

vec_merge <- function(x, event_perc = 0.2, sample_n = c(2, 3)){
  # Check if event_perc makes sense
  if (event_perc > 1 | event_perc <= 0){
    stop("event_perc should be between 0 to 1.")
  }
  # Check if sample_n makes sense
  if (any(sample_n < 2)){
    stop("sample_n should be at least larger than 2")
  }
  # Determine the event numbers
  n <- round(length(x) * event_perc)
  # Determine the sample number of each event
  sample_vec <- sample(sample_n, size = n, replace = TRUE)
  names(sample_vec) <- paste0("S", 1:n)
  # Check if the sum of sample_vec is larger than the length of x
  # If yes, stop the function and print a message 
  if (length(x) < sum(sample_vec)){
    stop("Too many samples. Decrease event_perc or sampel_n")
  }
  # Determine the number that will not be merged
  n2 <- length(x) - sum(sample_vec) 
  # Create a vector with replicated 1 based on m
  non_merge_vec <- rep(1, n2)
  names(non_merge_vec) <- paste0("N", 1:n2)
  # Combine sample_vec and non_merge_vec, and then randomly sorted the vector
  combine_vec <- c(sample_vec, non_merge_vec)
  combine_vec2 <- sample(combine_vec, size = length(combine_vec))
  # Expand the vector
  expand_list <- list(lengths = combine_vec2, values = names(combine_vec2))
  expand_vec <- inverse.rle(expand_list)
  # Create a data frame with x and expand_vec
  dat <- data.frame(number = x, 
                    group = factor(expand_vec, levels = unique(expand_vec)))
  dat$index <- 1
  dat2 <- aggregate(cbind(dat$number, dat$index), 
                    by = list(group = dat$group),
                    FUN = sum)
  # # Convert dat2 to a matrix, remove the group column
  dat2$group <- NULL
  mat <- as.matrix(dat2)
  return(mat)
}
Run Code Online (Sandbox Code Playgroud)

这是该功能的测试。我将该函数应用于从 1 到 10 的序列。如您所见,在本示例中,45被合并,并且89也被合并。

set.seed(123)
vec_merge(1:10)
#      number index
# [1,]      1     1
# [2,]      2     1
# [3,]      3     1
# [4,]      9     2
# [5,]      6     1
# [6,]      7     1
# [7,]     17     2
# [8,]     10     1
Run Code Online (Sandbox Code Playgroud)