2011-12-01 10 views
5

Ho una matrice grande da cui vorrei estrarre a caso una matrice più piccola. (Voglio fare questo 1000 volte, quindi in definitiva sarà in un ciclo.) Per esempio che ho questa matrice 9x9:selezionando le colonne specificate da un vettore casuale in R

mat=matrix(c(0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1, 
      0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0, 
      1,0,1,0,0,0,0,0,1,0,1,0,0,0,1), nrow=9) 

Da questa matrice, desidero un sottoinsieme casuale 3x3. Il trucco è che non voglio che nessuna delle somme di riga o colonna nella matrice finale sia uguale a 0. Un'altra cosa importante è che ho bisogno di conoscere il numero originale delle righe e delle colonne nella matrice finale. Quindi, se finisco per selezionare casualmente le righe 4, 5 e 7 e le colonne 1, 3 e 8, voglio che quegli identificatori siano facilmente accessibili nella matrice finale.

Ecco cosa ho fatto finora.

Innanzitutto, creo un vettore di numeri di riga e numeri di colonna. Sto cercando di mantenere questi allegati alla matrice per tutto il tempo.

r.num<-seq(from=1,to=nrow(mat),by=1)  #vector of row numbers 
c.num<-seq(from=0, to=(ncol(mat)+1),by=1) #vector of col numbers (adj for r.num) 

mat.1<-cbind(r.num,mat) 
mat.2<-rbind(c.num,mat.1) 

Ora ho una matrice 10x10 con identificatori. Posso selezionare le mie righe creando un vettore casuale e inserendo la matrice.

rand <- sample(r.num,3) 
temp1 <- rbind(mat.2[1,],mat.2[rand,])  #keep the identifier row 

Questo funziona bene! Ora voglio selezionare casualmente 3 colonne. Questo è dove mi trovo nei guai. Ho provato a farlo allo stesso modo.

rand2 <- sample(c.num,3) 
temp2 <- cbind(temp1[,1],temp1[,rand2]) 

Il problema è che alla fine con alcune somme di righe e colonne che sono 0. posso eliminare colonne che somma a 0 prima.

temp3 <- temp1[,which(colSums(temp1[2:nrow(temp1),])>0)] 
cols <- which(colSums(temp1[2:nrow(temp1),2:ncol(temp1)])>0) 
rand3 <- sample(cols,3) 
temp4 <- cbind(temp3[,1],temp3[,rand3]) 

Ma alla fine visualizzo un messaggio di errore. Per qualche ragione, a R non piace sottoporre la matrice in questo modo.

Quindi la mia domanda è, c'è un modo migliore per subset della matrice dal vettore casuale "rand3" dopo che le colonne zero sono state rimosse OPPURE c'è un modo migliore di selezionare casualmente tre righe e colonne complementari in modo tale che ci siano nessuno che somma a 0?

Grazie mille per il vostro aiuto!

+0

Qualora le finali 1000 matrici sottoinsieme essere unico? –

+0

Non è fondamentale. La matrice originale da cui provengo è 1174 righe e 455 colonne, quindi voglio ottenere un campionamento rappresentativo. Tuttavia, sono sicuro che esiste un numero finito di possibilità. L'unico problema sarebbe se ci fosse una sorta di pregiudizio di campionamento verso una delle sottomatrici uniche. – Laura

risposta

4

Se ho capito il problema, credo che questo dovrebbe funzionare:

mat=matrix(c(0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1, 
      0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,0, 
      1,0,1,0,0,0,0,0,1,0,1,0,0,0,1), nrow=9) 

smallmatrix = matrix(0,,nrow=3,ncol=3) 

while(any(apply(smallmatrix,2,sum) ==0) | any(apply(smallmatrix,1,sum) ==0)){ 
     cols = sample(ncol(mat),3) 
     rows= sample(nrow(mat),3) 
     smallmatrix = mat[rows,cols] 
} 

colnames(smallmatrix) = cols 
rownames(smallmatrix) = rows 
+2

Haha Ho quasi voluto postare la stessa risposta ma mi hai battuto per farlo! Penso solo nel valutare se le somme di righe e colonne sono zero, è più veloce usare 'rowSums' e' colSums': 'any (colSums (smallmatrix) == 0) | any (rowSums (smallmatrix) == 0) ' –

+0

Oops, ho appena notato che ci sono alcune righe che finiscono con una somma zero usando questo metodo. Altre idee? – Laura

+1

L'ho appena risolto. @SachaEpskamp lo ha capito sin dall'inizio. Non ho notato che la restrizione si applica anche alle righe. Quindi è solo aggiungendo un o per il momento. – aatrujillob

Problemi correlati