有人知道在矢量中添加数字组合的方法吗?
假设我正在经历一个for循环,每次我最终得到一个不同长度的向量,我怎么能组合这个向量的每个元素,使得我有2个,3个等元素的总和?
例如,如果我有:
vector <- c(1:5)
并希望像以下一样通过它:
element 1 + element 2; element 2 + element 3, etc
但是:
element 1 + element 2 + element 3
我该怎么做?值得注意的是,在许多矢量中,长度将是不同的。因此,虽然一个向量可能包含3个元素,但另一个可能包含12个元素。
我知道你可以做vector[1]+vector[2]
,但我需要一些方法来迭代整个向量,其中它考虑了上述注释。
答案 0 :(得分:2)
使用您可以使用combn
:
> combn(vector, 3, FUN = NULL, simplify = TRUE)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 1 1 1 1 1 2 2 2 3
[2,] 2 2 2 3 3 4 3 3 4 4
[3,] 3 4 5 4 5 5 4 5 5 5
这里的技巧是每个调用都会返回一个结果矩阵,你必须决定如何聚合和存储所有各种组合。
如果您不介意列表,那么以下内容应该可以解决问题:
> sapply(c(1:length(vector)),
function(x) {
combn(vector, x, FUN = NULL, simplify = TRUE)
})
答案 1 :(得分:2)
在这种情况下,我们需要获得对:
combn(3, 2)
<强>输出:强>
[,1] [,2] [,3]
[1,] 1 1 2
[2,] 2 3 3
由列生成对。
要访问每个元素并执行求和,我们选择定义一个带有组合和向量的辅助函数。
# Write a helper function
# sums of the index of the vector
comb_subset_sum = function(x, vec){
return(sum(vec[x]))
}
据此,我们可以直接使用combn
或使用sapply
。
combn
:
# Input Vector
vec = 1:5
# Length of vector
n = length(vec)
# Generate pairwise combinations and obtain pair_sum
# Specify the k (m in R)
m = combn(n, m = 2, FUN = comb_subset_sum, vec = vec)
sapply
用法:
# Input Vector
vec = 1:5
# Number of Observations
n = length(vec)
# Combinations
# Specify the k (m in R)
combinations = combn(n, m = 2)
# Obtain vectorized sum over subset
subset_summed = apply(combinations, 2, comb_subset_sum, vec = vec)
示例输出:
<强>组合强>:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 1 1 1 2 2 2 3 3 4
[2,] 2 3 4 5 3 4 5 4 5 5
<强> subset_summed 强>:
[1] 3 4 5 6 5 6 7 7 8 9
跟踪:
vec[1]+vec[2]=3
vec[1]+vec[3]=4
vec[1]+vec[4]=5
vec[1]+vec[5]=6
vec[2]+vec[3]=5
vec[2]+vec[4]=6
vec[2]+vec[5]=7
vec[3]+vec[4]=7
vec[3]+vec[5]=8
vec[4]+vec[5]=9
要获取跟踪输出,请在return()
中的comb_subset_sum()
之前添加以下内容:
cat(paste0("vec[",x,"]", collapse = "+"), "=", sum(vec[x]), "\n")
在这里,我们应用相同的逻辑,只是使组合的 k 值能够采用多个值。
# Input Vector
vec = 1:5
# Length of Vec
n = length(vec)
# Store output
o = vector('list',n)
for(i in seq_along(vec)){
o[[i]] = combn(n, i, FUN = comb_subset_sum, vec = vec)
}
注意: o
的每个元素的大小会随着组合数量增加然后减少而变化。
如果我们不关心向量元素值,那么我们可以用与获取向量元素的方式类似的方式对实际组合求和。
要生成对然后求和,请使用:
# Input Vector
vec = 1:5
# Length of Vec
n = length(vec)
# Generate all combinations (by column)
# Specify the k (m in R)
m = combn(n, m = 2)
# Obtain sum by going over columns
sum_m = apply(m, 2, sum)
或者一气呵成:
# Specify the k (m in R)
sum_inplace = combn(n, m = 2, FUN = sum)
平等:
all.equal(sum_m,sum_inplace)
而且,和以前一样,我们可以通过使用以下方式将其设置为在不同的 k 下获得所有总和:
# Input Vector
vec = 1:5
# Length of Vec
n = length(vec)
# Store output (varying lengths)
o = vector('list',n)
for(i in seq_along(vec)){
o[[i]] = combn(n, i, FUN = sum)
}
答案 2 :(得分:0)
您可能正在寻找rollsum
包中的zoo
,您可以在其中指定要添加的元素数量:
lapply(2:5, function(i) zoo::rollsum(1:5, i))
[[1]]
[1] 3 5 7 9 # two elements roll sum
[[2]]
[1] 6 9 12 # three elements roll sum
[[3]]
[1] 10 14 # four elements roll sum
[[4]]
[1] 15 # five elements roll sum
答案 3 :(得分:0)
以下内容依赖于数字的二进制表示。基本上,你有2 ^ n个组合来检查。通过以二进制形式写入1到2 ^ n之间的任何数字&#39; n&#39;比特,你有你可能想要的所有元素的排列。
number2binary
函数来自Paul Hiestra的答案:How to convert integer number into binary vector?
number2binary = function(number, noBits) {
binary_vector = rev(as.numeric(intToBits(number)))
if(missing(noBits)) {
return(binary_vector)
} else {
binary_vector[-(1:(length(binary_vector) - noBits))]
}
}
vector <- 1:5
n <- length(vector)
comp_sum <- function(x) {
binary <- number2binary(x, noBits = n)
result <- sum(vector[which(binary==1)])
names(result) <- paste(which(binary == 1), collapse = "+")
return(result)
}
binaries <- sapply(1:2^n-1, comp_sum)
注意:我只需要2 ^ n - 1,因为你不需要&#34;零&#34;。通过在comp_sum
函数中添加一些条件,您只能选择两个元素或三个元素的总和...