Исключение определенных комбинаций из функции combn в R

Я пытаюсь исключить все комбинации, созданные функцией combn, состоящей из «var4» и «var5». Вот код, который на данный момент не работает:

mod_headers <- c("var1", "var2", "var3", "var4", "var5", "var6")

f <- function(){
  for(i in 1:length(mod_headers)){
    tab <- combn(mod_headers,i,function(mod_headers){
      if (combn(mod_headers,i) %in% c("var4","var5")) {return()}
    })
    for(j in 1:ncol(tab)){
      tab_new <- c(tab[,j])
      mod_tab_new <- c(tab_new, "newcol")
      print(mod_tab_new)
    }
  }
}

f()

Спасибо за вашу помощь!


person New2coding    schedule 03.08.2017    source источник
comment
Это нормально, если что-то происходит само по себе, вы просто не хотите, чтобы они происходили вместе?   -  person AkselA    schedule 03.08.2017
comment
да, именно так, я не хочу, чтобы они происходили вместе. Спасибо!   -  person New2coding    schedule 03.08.2017


Ответы (5)


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

mod_headers <- c("var1", "var2", "var3", "var4", "var5", "var6")


combn_with_exclusion <- function(x, n, exclude){
  full <- combn(x, n)
  # remove any columns that have all elements of `exclude`
  full[, !apply(full, 2, function(y) all(exclude %in% y))]
}

combn_with_exclusion(mod_headers, 2, c("var4", "var5"))
person Benjamin    schedule 03.08.2017
comment
Спасибо, ваш сценарий дает мне желаемый результат, однако я не хотел бы изменять структуру своего кода, потому что это часть более надежного кода (я просто удалил все части, которые здесь не нужны). Есть ли способ применить FUN непосредственно к функции combn? Спасибо - person New2coding; 03.08.2017
comment
Я думаю, что ответ Эндрю Густара может быть тем, что вы хотите использовать вместо своего f(). - person Benjamin; 03.08.2017
comment
@ New2coding FUN в функции combn применяется к каждой отдельной комбинации, и я не могу придумать способ заставить его полностью опустить комбинацию, если она соответствует вашим критериям. Например, ifelse, чтобы заменить его на NULL, не работает. - person Andrew Gustar; 03.08.2017
comment
Хорошо, спасибо за ваш комментарий. Я пытаюсь заставить этот фрагмент кода работать, потому что он является частью другого моего кода. Я пытаюсь исключить коррелированные переменные из GLModel, исключив имена коррелированных заголовков (исходное сообщение здесь: stackoverflow.com/questions/45466513/) - person New2coding; 03.08.2017

Вот еще один способ: создать список всех комбинаций, а затем исключить те, которые содержат как var4, так и _2 _...

lapply(
   lapply(1:length(mod_headers),
        function(i) combn(mod_headers, i)), 
   function(x) x[,apply(x, 2, function(y) !all(c("var4", "var5") %in% y))]) 

[[1]]
[1] "var1" "var2" "var3" "var4" "var5" "var6"

[[2]]
     [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]   [,10]  [,11]  [,12]  [,13]  [,14] 
[1,] "var1" "var1" "var1" "var1" "var1" "var2" "var2" "var2" "var2" "var3" "var3" "var3" "var4" "var5"
[2,] "var2" "var3" "var4" "var5" "var6" "var3" "var4" "var5" "var6" "var4" "var5" "var6" "var6" "var6"

[[3]]
     [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]   [,10]  [,11]  [,12]  [,13]  [,14]  [,15]  [,16] 
[1,] "var1" "var1" "var1" "var1" "var1" "var1" "var1" "var1" "var1" "var2" "var2" "var2" "var2" "var2" "var3" "var3"
[2,] "var2" "var2" "var2" "var2" "var3" "var3" "var3" "var4" "var5" "var3" "var3" "var3" "var4" "var5" "var4" "var5"
[3,] "var3" "var4" "var5" "var6" "var4" "var5" "var6" "var6" "var6" "var4" "var5" "var6" "var6" "var6" "var6" "var6"

...etc
person Andrew Gustar    schedule 03.08.2017

Я пробовал это только на TIO, так что без тестирования, но держу пари, что эта версия будет быстрее для больших наборов, если это будет важно.

m <- c("var2", "var3", "var4", "var5", "var6")
comb <- combn(m, 3)
csums <- colSums((comb == "var4") + (comb == "var5"))
comb[, csums < 2]
#      [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]  
# [1,] "var2" "var2" "var2" "var2" "var2" "var3" "var3"
# [2,] "var3" "var3" "var3" "var4" "var5" "var4" "var5"
# [3,] "var4" "var5" "var6" "var6" "var6" "var6" "var6"

Или эквивалент OP f():

f2 <- function(m=mod_headers) {
    lapply(1:length(m), function(x) {
      comb <- combn(m, x)
      csums <- colSums((comb == "var4") + (comb == "var5"))
      comb[, csums < 2]
    })
}
person AkselA    schedule 03.08.2017
comment
Это мое решение: f ‹- function () {for (i in 1: length (mod_headers)) {tab‹ - combn (mod_headers, i) for (j in 1: ncol (tab)) {tab_new ‹- c ( tab [, j]) mod_tab_new ‹- c (tab_new, newcol) if (all (c (var4, var5)% in% mod_tab_new)) следующая печать (mod_tab_new)}}} f () - person New2coding; 03.08.2017

Это мое решение:

f <- function(){
  for(i in 1:length(mod_headers)){
      tab <- combn(mod_headers,i)
      for(j in 1:ncol(tab)){
        tab_new <- c(tab[,j])
        mod_tab_new <- c(tab_new, "newcol")
        if (all(c("var4","var5") %in% mod_tab_new)) next
        print(mod_tab_new)
    }
  }
}

f()
person New2coding    schedule 03.08.2017

Я использовал эту веб-страницу, чтобы сократить список комбинаций N-Way, учитывая другой набор комбинаций N-Way. Вот небольшая модификация кода Бенджамина.

mod_headers <- c("var1", "var2", "var3", "var4", "var5", "var6")

combn_NWayExclusion <- function(x, n, exclude){
   full <- combn(x, n); EXC<-combn(exclude, n)
   UU<-lapply(1:ncol(EXC),function(i) !apply(full, 2, function(y) all(EXC[,i] %in% y)))
   full[,!apply(do.call(rbind,UU),2,function(u){any(u=="FALSE")})]
   }

combn_NWayExclusion(mod_headers, 2, c("var4", "var5"))
person emart86    schedule 27.01.2021