Получение исключенных элементов для каждой из комбинаций combn(n,k)

StackOverflow https://stackoverflow.com/questions/2490860

  •  21-09-2019
  •  | 
  •  

Вопрос

Предположим, мы сгенерировали матрицу A где каждый столбец содержит одну из комбинаций n элементы в группах из k.Таким образом, его размеры будут составлять k,choose(n,k).Такая матрица создается при подаче команды combn(n,k).То, что я хотел бы получить, - это еще одна матрица B с размерами (n-k),choose(n,k), где каждый столбец B[,j] будет содержать исключенные n-k элементы A[,j].

Вот пример того, как я использую таблицу get B.Считаете ли вы, что это безопасный метод в использовании?Есть ли другой способ?

n <- 5 ; k <- 3
(A <- combn(n,k))
(B <- combn(n,n-k)[,choose(n,k):1])

Другой пример

x<-c(0,1,0,2,0,1) ; k<- 4
(A <- combn(x,k))
(B <- combn(x,length(x)-k)[,choose(length(x),k):1])

Это предыдущий вопрос мое мнение является частью этой проблемы.
Спасибо.

Это было полезно?

Решение

используя Musa's идея

B <- apply(A,2,function(z) x[is.na(pmatch(x,z))])

что касается первого примера:

B <- apply(A,2,function(z) (1:n)[is.na(pmatch((1:n),z))])

Другие советы

Используйте setdiff функция:

N <- 5
m <- 2    
A <- combn(N,m)
B <- apply(A,2,function(S) setdiff(1:N,S))

ИЗМЕНЕННЫЙ:Описанное выше работает только тогда, когда векторы имеют уникальные значения.Для второго примера мы напишем замену для setdiff который может обрабатывать повторяющиеся значения.Мы используем rle чтобы подсчитать количество встречаемости каждого элемента в двух наборах, вычтите количество, затем инвертируйте RLE:

diffdup <- function(x,y){
  rx <- do.call(data.frame,rle(sort(x)))
  ry <- do.call(data.frame,rle(sort(y)))
  m <- merge(rx,ry,by='values',all.x=TRUE)
  m$lengths.y[is.na(m$lengths.y)] <- 0
  rz <- list(values=m$values,lengths=m$lengths.x-m$lengths.y)
  inverse.rle(rz)
}

x<-c(0,1,0,2,0,1) ; k<- 4
A <- combn(x,k)
B <- apply(A,2,function(z) diffdup(x,z))

Вот более общее решение (вы можете заменить X любым вектором, содержащим уникальные записи):

X<-1:n
B<-apply(A,2,function(x,ref) ref[!ref%in%x],ref=X)
B<-do.call(cbind,B)

Принимая во внимание, что в вашем предыдущем вопросе x и y не были наборами, при условии, что столбцы A являются правильными наборами, приведенный выше код должен работать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top