2011-12-01 19 views
5

Mam dużą matrycę, z której chciałbym losowo wyodrębnić mniejszą macierz. (Chcę zrobić to 1000 razy, więc ostatecznie będzie w pętli for.) Powiedzmy na przykład, że mam to macierz 9x9:wybierając kolumny określone przez losowy wektor w 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) 

Od tej macierzy, chciałbym losowy podzbiór 3x3. Sztuczka polega na tym, że nie chcę, aby któraś z sum wierszy lub kolumn w ostatniej macierzy wynosiła 0. Kolejną ważną rzeczą jest to, że muszę znać pierwotną liczbę wierszy i kolumn w ostatecznej macierzy. Tak więc, jeśli losowo wybiorę wiersze 4, 5 i 7 oraz kolumny 1, 3 i 8, chcę, aby te identyfikatory były łatwo dostępne w ostatecznej macierzy.

Oto, co zrobiłem do tej pory.

Najpierw tworzę wektor numerów wierszy i numerów kolumn. Próbuję zachować te dołączone do matrycy w całym tekście.

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) 

Teraz mam matrycę 10x10 z identyfikatorami. Mogę wybrać moje wiersze, tworząc losowy wektor i podzbioru macierzy.

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

To działa dobrze! Teraz chcę losowo wybrać 3 kolumny. To tu mam kłopoty. Próbowałem robić to w ten sam sposób.

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

Problem polega na tym, że kończę z pewnymi sumami wierszy i kolumn o wartości 0. Mogę całkowicie wyeliminować kolumny, które sumują się do 0.

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

Ale kończę z komunikatem o błędzie. Z jakiegoś powodu, R nie lubi w ten sposób przesłonić matrycy.

Moje pytanie brzmi: czy istnieje lepszy sposób podziału macierzy na losowy wektor "rand3" po usunięciu zerowych kolumn? Czy istnieje lepszy sposób na losowe wybieranie trzech uzupełniających się wierszy i kolumn? brak sumy do 0?

Dziękuję bardzo za pomoc!

+0

Jeżeli ostateczne 1000 macierze podzbiór być wyjątkowy? –

+0

To nie jest krytyczne. Oryginalna macierz, z której pobieram próbki, to 1174 wiersze i 455 kolumn, więc chcę uzyskać reprezentatywne próbki. Jestem jednak pewien, że istnieje skończona liczba możliwości. Jedyny kłopot polegałby na tym, że istniała jakaś skłonność do próbkowania w kierunku jednej z wyjątkowych podmatryc. – Laura

Odpowiedz

4

Jeśli zrozumiałem swój problem, myślę, że to będzie dział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 Prawie chciałem zamieścić tę samą odpowiedź, ale biłeś mnie! Myślę tylko, że podczas oceniania, czy sumy wierszy i kolumn są równe zero, szybciej jest użyć 'rowSums' i' colSums': 'any (colSums (smallmatrix) == 0) | any (rowSums (smallmatrix) == 0) ' –

+0

Ups, właśnie zauważyłem, że istnieje kilka wierszy, które kończą się sumą zerową przy użyciu tej metody. Jakieś inne pomysły? – Laura

+1

Naprawiłem to. @SachaEpskamp ma to od samego początku. Nie zauważyłem, że ograniczenie dotyczyło również rzędów. Więc po prostu dodajesz lub na chwilę. – aatrujillob

Powiązane problemy