2011-12-01 16 views
5

Tengo una matriz grande de la cual me gustaría extraer al azar una matriz más pequeña. (Quiero hacer esto 1000 veces, por lo que en última instancia será en un bucle.) Digamos por ejemplo que tengo esta matriz 9x9:seleccionando columnas especificadas por un vector aleatorio en 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) 

De esta matriz, me gustaría un subconjunto aleatorio de 3x3. El truco es que no quiero que ninguna de las sumas de fila o columna en la matriz final sea 0. Otra cosa importante es que necesito saber el número original de las filas y columnas en la matriz final. Entonces, si termino seleccionando aleatoriamente las filas 4, 5 y 7 y las columnas 1, 3 y 8, quiero tener esos identificadores fácilmente accesibles en la matriz final.

Esto es lo que he hecho hasta ahora.

Primero, creo un vector de números de fila y columna. Estoy tratando de mantener estos conectados a la matriz en todo momento.

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) 

Ahora tengo una matriz de 10x10 con identificadores. Puedo seleccionar mis filas creando un vector aleatorio y subdividiendo la matriz.

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

¡Esto funciona bien! Ahora quiero seleccionar aleatoriamente 3 columnas. Aquí es donde me encuentro en problemas. Intenté hacerlo de la misma manera.

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

El problema es que termino con algunos de fila y columna sumas que son 0. I puede eliminar columnas que suma a 0 primero.

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

Pero termino con un mensaje de error. Por alguna razón, a R no le gusta subconjuntar la matriz de esta manera.

Así que mi pregunta es, ¿hay una mejor manera de subconjunto de la matriz por el vector aleatorio "rand3" después de que las columnas cero se han eliminado O hay una mejor manera de seleccionar aleatoriamente tres filas y columnas complementarias tales que hay ninguno que suma a 0?

¡Muchas gracias por su ayuda!

+0

En caso de que las matrices finales de 1000 subconjunto ser único? –

+0

No es crítico. La matriz original de la que estoy tomando muestras es de 1174 filas y 455 columnas, por lo que quiero obtener un muestreo representativo. Sin embargo, estoy seguro de que hay un número finito de posibilidades. El único problema sería si hubiera algún tipo de sesgo de muestreo hacia una de las submatrices únicas. – Laura

Respuesta

4

Si he entendido su problema, creo que esto funcionaría:

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 ¡Casi quería publicar la misma respuesta pero me ganaste! Solo creo que al evaluar si las sumas de filas y columnas son cero, es más rápido usar 'rowSums' y' colSums': 'any (colSums (smallmatrix) == 0) | any (rowSums (smallmatrix) == 0) ' –

+0

Vaya, acabo de notar que hay algunas filas que terminan con una suma cero usando este método. ¿Alguna otra idea? – Laura

+1

Lo acabo de arreglar. @SachaEpskamp lo entendió bien desde el principio. No noté que la restricción también se aplicaba a las filas. Entonces solo está agregando un o por el momento. – aatrujillob

Cuestiones relacionadas