2017-07-24 2 views
0

supposer que j'ai une grande matrice (matrice_1) de 2000 colonnes. Chaque cellule a une valeur de 0 ou 1. Je veux trouver la meilleure combinaison de 10 colonnes. La meilleure combinaison donne le nombre maximum de valeurs non-0 par rangée. Ainsi, il donne essentiellement au maximumtrouver la meilleure combinaison de colonnes dans une matrice

sum (apply (matrix_2, 1, function(x) any(x == 1))) 

Je ne peux pas passer par toutes les combinaisons possibles car il est trop de calculs (il y a 2.758988e + 26). Aucune suggestion?

Pour un exemple prendre cette matrice, il dispose de 4 lignes et je ne suis ramassait 2 colonnes à la fois

mat <- matrix (c(1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0), nrow = 4, byrow = FALSE) 
mat 
# combination of columns 2 and 3 is best: 3 rows with at least a single 1 value 
sum (apply (mat[, c(2, 3)], 1, function(x) any (x == 1))) 
# combination of columns 1 and 2 is worse: 2 rows with at least a single 1 value 
sum (apply (mat[, c(1, 2)], 1, function(x) any (x == 1))) 
+0

Combien de lignes dans votre matrice? – CPak

+0

100-200 lignes. Dépend de l'application –

+0

Vous ne pouvez pas commander vos colonnes par 'colSums (col)' et choisissez le top 10? Je demande parce que je ne suis pas sûr à 100% ce que vous voulez, et cela m'aide à avoir une meilleure idée de ce que vous cherchez. – CPak

Répondre

0

Vous pouvez utiliser une fonction comme ça ...

find10 <- function(mat,n=10){ 
    cols <- rep(FALSE,ncol(mat)) #columns to exclude 
    rows <- rep(TRUE,nrow(mat)) #rows to include 
    for(i in 1:n){ 
    colsums <- colSums(mat[rows,]) 
    colsums[cols] <- -1 #to exclude those already accounted for 
    maxcol <- which.max(colsums) 
    cols[maxcol] <- TRUE 
    rows <- rows & !as.logical(mat[,maxcol]) 
    } 
    return(which(cols)) 
} 

Il semble pour la colonne avec la plupart des non-zéros, supprime ces lignes de la comparaison et répète. Il renvoie les numéros de colonnes des n meilleures colonnes.

Un exemple ...

m <- matrix(sample(0:1,100,prob = c(0.8,0.2),replace=TRUE),nrow=10) 

m 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] 0 1 0 0 0 0 0 1 1  0 
[2,] 1 0 0 0 0 0 0 0 1  1 
[3,] 0 0 0 0 1 0 0 0 0  0 
[4,] 0 0 0 1 0 1 0 1 0  1 
[5,] 0 0 0 0 1 0 0 1 0  0 
[6,] 0 0 0 1 0 1 1 0 0  0 
[7,] 0 0 1 0 0 0 0 0 0  0 
[8,] 0 0 0 0 0 0 0 0 1  0 
[9,] 0 0 0 0 0 0 0 1 0  0 
[10,] 0 0 0 0 0 0 0 0 0  0 

find10(m,5) 
[1] 3 4 5 8 9 

Il est également livré avec 2,3 pour l'exemple que vous donnez.

+0

Solution intéressante. Je dois y réflechir! –

+1

oui, vous avez raison! Très bonne réponse! Merci beaucoup! –