我在 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)
目前我正在寻求帮助,即使是最简单的步骤:组合向量中的位置。我尝试了sample和split函数的多种变体,但遇到了死胡同。例如,sum(sample(ex.have,2))将两个随机选择的位置相加(或sum(sample(ex.have,rpois(1,2))将在n值中添加一些随机性),但我不确定如何利用它来实现所需的数据集。详尽的搜索导致了多篇关于组合向量的文章,但不是向量中的位置,所以如果这是重复的,我深表歉意。任何关于如何处理这些问题的建议将不胜感激。
这是我设计的一个函数来执行您所描述的任务。
该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 的序列。如您所见,在本示例中,4和5被合并,并且8和9也被合并。
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)