R - 在向量中添加元素组合

时间:2016-07-05 15:06:58

标签: r vector

有人知道在矢量中添加数字组合的方法吗?

假设我正在经历一个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],但我需要一些方法来迭代整个向量,其中它考虑了上述注释。

4 个答案:

答案 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)

生成配对ID

在这种情况下,我们需要获得对:

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

1 k 的总和:

直接

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 的求和:

在这里,我们应用相同的逻辑,只是使组合的 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 使用

而且,和以前一样,我们可以通过使用以下方式将其设置为在不同的 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函数中添加一些条件,您只能选择两个元素或三个元素的总和...