如果我有一组值,例如
c(1,2,5,6,7,15,19,20)
我想随机选择2个值,它们的总和等于20。从上面的列表中,我希望看到的样本可能是
[19,1], [15,5]
我如何在R中做到这一点。我们将不胜感激。
答案 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
的一半,因为另一半将是同一对。