2010-03-22 7 views
2

Supposons que nous ayons généré une matrice A où chaque colonne contient l'une des combinaisons de n éléments dans les groupes k. Ainsi, ses dimensions seront k,choose(n,k). Une telle matrice est produite donnant la commande combn(n,k). Ce que je voudrais obtenir est une autre matrice B avec les dimensions (n-k),choose(n,k), où chaque colonne B[,j] contiendra les exclus n-k éléments de A[,j].Obtention des éléments exclus pour chacune des combinaisons combn (n, k)

Voici un exemple de la façon dont j'utilise la table get B. Pensez-vous que c'est une méthode sûre à utiliser? Y a-t-il un autre moyen?

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

Un autre exemple

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]) 

Ce previous question à moi fait partie de ce problème.
Merci.

Répondre

4

à l'aide de Musa idea

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

en ce qui concerne le premier exemple:

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

Voici une solution plus générale (vous pouvez remplacer X par un vecteur contenant des entrées uniques):

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

Alors que dans votre x question précédente et y étaient pas ensembles, à condition que les colonnes de A sont des ensembles appropriés , le code ci-dessus devrait fonctionner.

+0

Merci, mais dans la plupart des cas, il y aura des doublons comme cela a été le cas dans la question référencée . –

2

Utilisez la fonction setdiff:

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

MODIFIÉ: Les travaux ci-dessus que lorsque les vecteurs ont uniques valeurs. Pour le deuxième exemple, nous écrivons un remplacement pour setdiff qui peut gérer les valeurs en double. Nous utilisons rle pour compter le nombre d'occurence de chaque élément dans les deux ensembles, soustraire les comptes, puis inverser la 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)) 
+0

Merci. Comment doit-on modifier pour travailler pour le 2ème exemple aussi? –

+0

Modifié pour ajouter une solution pour le deuxième problème aussi. –

+0

Au lieu de cette combinaison, vous pouvez simplement inverser la solution gd047: 'apply (A, 2, fonction (S) x [setdiff (1: N, S)])' où 'N <-length (x)'. – Marek