从给定的数字列表中随机选择值以添加到r中的某个值

时间:2019-02-21 08:18:53

标签: r

如果我有一组值,例如

c(1,2,5,6,7,15,19,20)

我想随机选择2个值,它们的总和等于20。从上面的列表中,我希望看到的样本可能是

[19,1], [15,5]

我如何在R中做到这一点。我们将不胜感激。

4 个答案:

答案 0 :(得分:0)

这将计算输入向量的所有可能组合,因此,如果输入向量过长,则可能会出现问题。

getVal <- function(vec,val) {
  comb = combn(vec, 2)
  idx = colSums(comb) == val
  if (sum(idx)) {
      return(comb[,idx][,sample(sum(idx),1)])
  }
  return(FALSE)
}

vec = (c(1,4,6,9))
val = 10
getVal(vec,val)
>>[1] 1 9

val = 11
>>[1] FALSE
getVal(vec,val)

答案 1 :(得分:0)

对于较小的值向量,您可以通过计算值中所有对的组合来进行详尽的搜索。示例:

> values = c(1,2,5,6,7,15,19,20)
> pairs = matrix(values[t(combn(length(values),2))],ncol=2)

这是values中所有对的2列矩阵。现在对行求和,并寻找目标值20:

> targets = apply(pairs,1,sum)==20
> pairs[targets,]
     [,1] [,2]
[1,]    1   19
[2,]    5   15

pairs的大小增加,因此,如果您有100 values,则pairs将有近5000行。

答案 2 :(得分:0)

您可以使用sample()-功能和while循环来完成此操作。这不是最漂亮的解决方案,但是肯定可以轻松实现。

首先,您从向量中采样两个值并将其存储在对象中,例如:

values <- c(1, 2, 5, 6, 7, 15, 19, 20)

randomTwo <- sample(values, 2)

然后开始while循环。此循环检查两个采样值的模10之和是否等于0(我假设您是从问题示例中得出模的意思,请参见https://en.wikipedia.org/wiki/Modulo_operation以了解其作用)。如果该操作不等于0,则循环将采样两个新值,直到该操作等于零为止,您将获得两个值。

是这样的:

while (sum(randomTwo) %% 10 != 0) {
    randomTwo <- sample(values, 2)
}

现在,与检查所有组合相比,这可能需要更多的迭代,并且根据机会而可能需要更少的迭代。如果您只有这么小的向量,那么这是一个不错的解决方案。祝你好运!

答案 3 :(得分:0)

通过某种方式您无需计算庞大的矩阵(速度更快):

findpairs=function(a,sum,num){
  list=list()
  aux=1
  for (i in 1:length(a)){
    n=FALSE
    n=which((a+a[i])==sum)
    if (length(n)){
      for (j in n){
        if (j!=i){
        list[[aux]]=c(a[i],a[j])
        aux=aux+1
        }
      }
    }
  }
  return(sample(list[1:(length(list)/2),num))
}

a=c(1,2,5,6,19,7,15,20)
a=a[order(a)]
sum=20
findpairs(a,sum,2)
[[1]]
[1]  5 15

[[2]]
[1] 1  19

问题是它会重复。
修改
解决了。只需拿list的一半,因为另一半将是同一对。