Как я могу заставить этот итеративный код комбинации l oop работать с более чем x на комбинацию? - PullRequest
0 голосов
/ 15 января 2020

Я нашел этот спасительный код, созданный @QuantIbex. Он создает комбинации переменных итеративно для использования в al oop, не генерируя их заранее и не сохраняя их.

Первый ответ здесь

## Function definition
gen.next.cbn <- function(cbn, n){
    ## Generates the combination that follows the one provided as input
    cbn.bin      <- rep(0, n)
    cbn.bin[cbn] <- 1
    if (tail(cbn.bin, 1) == 0){
        ind <- tail(which(cbn.bin == 1), 1)
        cbn.bin[c(ind, ind+1)] <- c(0, 1)
    }else{
        ind <- 1 + tail(which(diff(cbn.bin) == -1), 1)
        nb  <- sum(cbn.bin[-c(1:ind)] == 1)
        cbn.bin[c(ind-1, (n-nb+1):n)] <- 0
        cbn.bin[ind:(ind+nb)]         <- 1
    }
    cbn <- which(cbn.bin == 1)
}

## Example parameters
n   <- 6
k   <- 3

## Iteration example
for (i in 1:choose(n, k)){
    if (i == 1){
        cbn <- 1:k
    }else{
        cbn <- gen.next.cbn(cbn, n)
    }
    print(cbn)
}

# [1] 1 2 3
# [1] 1 2 4
# [1] 1 2 5
# [1] 1 2 6
# [1] 1 3 4
# [1] 1 3 5
# [1] 1 3 6
# [1] 1 4 5
# [1] 1 4 6
# [1] 1 5 6
# [1] 2 3 4
# [1] 2 3 5
# [1] 2 3 6
# [1] 2 4 5
# [1] 2 4 6
# [1] 2 5 6
# [1] 3 4 5
# [1] 3 4 6
# [1] 3 5 6
# [1] 4 5 6

Сам код выходит за рамки моих собственных технических возможностей в R. Я смог адаптировать его для своего использования и вставить свой анализирует в l oop и работает очень хорошо. Одна из вещей, которую я не смог понять, это как сделать так, чтобы go было выполнено более чем по x числу переменных на комбинацию за раз.

В приведенном выше коде n = количество переменных для использоваться для генерации комбинаций. k = количество переменных в комбинации. В примере k = 3. Я могу изменить k на все, что захочу, но есть ли способ для k равный диапазон, такой как k = 3: 10?

Я устанавливаю значения:

n <- 31
k <- 3:10

Это останавливается однажды с комбинациями 3 и дает мне следующее:

Warning messages:
1: In 1:choose(n, k) :
  numerical expression has 8 elements: only the first used
2: In 1:k : numerical expression has 8 elements: only the first used

Я знаю, что многие люди предупреждают о том, насколько медленными являются петли, и, вероятно, предупредят меня, что комбинации из 10 будут длиться вечно, но это вещи, которые я принимаю.

Ответы [ 2 ]

1 голос
/ 15 января 2020

Я считаю,

  • один из способов достижения sh того, что вы хотите начать использовать combn;
    • Но я заметил, что вы избегаете повторения элементов в комбинациях. Поэтому вам нужно будет исключить повторения ... Я включил пример кода для функции для него.
  • После этого вы можете заменить l oop на lapply для эффективности и используйте функцию.

    n<-31
    combnWoRepl<-function(n,k){
        abc<-combn(1:n,k)
        abc<-t(abc)
        abc<-data.frame(abc)
        colnames(abc)<-c("a","b","c")
        abc[!abc$a==abc$b,]
    }
    
    ResultList<-lapply(3:10,function(x){
        combnWoRepl(n,x)
    })
    
1 голос
/ 15 января 2020

Поскольку вы не возражаете против циклов, почему бы просто не выполнить итерацию по элементам k?

## Example parameters
n   <- 6
k <- 1:3

for(j in seq_along(k))
{
  ## Iteration example
  for (i in 1:choose(n, k[j])){
      if (i == 1){
          cbn <- 1:k[j]
      }else{
          cbn <- gen.next.cbn(cbn, n)
      }
      print(cbn)
  }
}

Вывод:

#> [1] 1
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5
#> [1] 6
#> [1] 1 2
#> [1] 1 3
#> [1] 1 4
#> [1] 1 5
#> [1] 1 6
#> [1] 2 3
#> [1] 2 4
#> [1] 2 5
#> [1] 2 6
#> [1] 3 4
#> [1] 3 5
#> [1] 3 6
#> [1] 4 5
#> [1] 4 6
#> [1] 5 6
#> [1] 1 2 3
#> [1] 1 2 4
#> [1] 1 2 5
#> [1] 1 2 6
#> [1] 1 3 4
#> [1] 1 3 5
#> [1] 1 3 6
#> [1] 1 4 5
#> [1] 1 4 6
#> [1] 1 5 6
#> [1] 2 3 4
#> [1] 2 3 5
#> [1] 2 3 6
#> [1] 2 4 5
#> [1] 2 4 6
#> [1] 2 5 6
#> [1] 3 4 5
#> [1] 3 4 6
#> [1] 3 5 6
#> [1] 4 5 6

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

В качестве сноски, выбор набора из 10 элементов из 20 с использованием этого метода (без моего добавления) отнимает у моего компьютера около минуты, что я бы прожил с, если бы мне только нужно было запускать это время от времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...