Произвольно выберите значения из заданного списка номеров, чтобы добавить к определенному значению в r - PullRequest
0 голосов
/ 21 февраля 2019

Если у меня есть набор значений, таких как

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

, и я хочу случайным образом выбрать 2 значения, сумма которых равна 20. Из приведенного выше списка возможные примеры, которые я хотел бы видеть, были бы

[19,1], [15,5]

Как мне это сделать в R. Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

0 голосов
/ 21 февраля 2019

В способе, где вам не нужно вычислять простую матрицу (намного быстрее):

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, так как другая половина будет такими же парами.

0 голосов
/ 21 февраля 2019

Для небольшого вектора значений вы можете выполнить исчерпывающий поиск, разработав все комбинации пар в значениях.Пример:

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

Это матрица из 2 столбцов всех пар из values.Теперь суммируйте строки и найдите целевое значение 20:

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

Размер pairs увеличивается так, что если у вас 100 values, то pairs будет иметь почти 5000 строк.

0 голосов
/ 21 февраля 2019

Вы можете сделать это с помощью sample() -функции и цикла while.Это не самое красивое решение, но его просто реализовать наверняка.

Сначала вы выбираете два значения из вектора и сохраняете их в объекте, например:

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

randomTwo <- sample(values, 2)

Затем выначни тебя пока-петля.Этот цикл проверяет, равна ли сумма двух выбранных значений по модулю 10 0 (я предположил, что вы имели в виду по модулю из примеров в вашем вопросе, см. https://en.wikipedia.org/wiki/Modulo_operation, чтобы узнать, что он делает).Если операция не равна 0, цикл выбирает два новых значения, пока операция не станет равной нулю, и вы получите два значения.

Вот как это выглядит:

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

Теперь это может занять больше итераций, чем проверка всех комбо, и это может занять меньше, в зависимости от случая.Если у вас есть только этот маленький вектор, то это хорошее решение.Удачи!

0 голосов
/ 21 февраля 2019

Это вычисляет все возможные комбинации вашего входного вектора, поэтому, если это очень долго, это может быть проблемой.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...