выбор столбцов, заданных случайным вектором в R

У меня есть большая матрица, из которой я хотел бы случайным образом извлечь меньшую матрицу. (Я хочу сделать это 1000 раз, так что в конечном итоге это будет цикл for.) Скажем, например, что у меня есть эта матрица 9x9:

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)

Из этой матрицы я хотел бы случайное подмножество 3x3. Уловка заключается в том, что я не хочу, чтобы какая-либо сумма строк или столбцов в окончательной матрице была равна 0. Еще одна важная вещь состоит в том, что мне нужно знать исходное количество строк и столбцов в окончательной матрице. Итак, если я случайно выберу строки 4, 5 и 7 и столбцы 1, 3 и 8, я хочу, чтобы эти идентификаторы были легко доступны в окончательной матрице.

Вот что я сделал до сих пор.

Сначала я создаю вектор номеров строк и номеров столбцов. Я стараюсь, чтобы они были прикреплены к матрице повсюду.

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)

Теперь у меня есть матрица 10х10 с идентификаторами. Я могу выбирать свои строки, создавая случайный вектор и создавая подмножества матрицы.

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

Это хорошо работает! Теперь я хочу случайным образом выбрать 3 столбца. Вот где у меня проблемы. Я пробовал делать то же самое.

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

Проблема в том, что я получаю некоторые суммы строк и столбцов, которые равны 0. Я могу сначала удалить столбцы, сумма которых равна 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])

Но я получаю сообщение об ошибке. По какой-то причине R не любит таким образом подмножество матрицы.

Итак, мой вопрос: есть ли лучший способ подмножества матрицы случайным вектором "rand3" после удаления нулевых столбцов ИЛИ есть лучший способ случайным образом выбрать три дополнительные строки и столбцы, чтобы не было ни одной такой суммы для 0?

Большое вам спасибо за вашу помощь!


person Laura    schedule 01.12.2011    source источник
comment
Должны ли последние 1000 матриц подмножества быть уникальными?   -  person Sacha Epskamp    schedule 01.12.2011
comment
Это не критично. Исходная матрица, из которой я отбираю выборку, состоит из 1174 строк и 455 столбцов, поэтому я хочу получить репрезентативную выборку. Однако я уверен, что существует ограниченное количество возможностей. Единственная проблема могла бы возникнуть, если бы было какое-то смещение выборки в сторону одной из уникальных подматриц.   -  person Laura    schedule 01.12.2011


Ответы (1)


Если бы я понял вашу проблему, думаю, это сработало бы:

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
person aatrujillob    schedule 01.12.2011
comment
Ха-ха, я почти хотел опубликовать тот же ответ, но вы меня опередили! Я думаю, что при оценке, если суммы строк и столбцов равны нулю, быстрее использовать rowSums и colSums: any(colSums(smallmatrix)==0) | any(rowSums(smallmatrix)==0) - person Sacha Epskamp; 01.12.2011
comment
К сожалению, я только что заметил, что при использовании этого метода некоторые строки заканчиваются нулевой суммой. Есть другие идеи? - person Laura; 02.12.2011
comment
Я только что починил. @SachaEpskamp понял это с самого начала. Я не заметил, что ограничение распространяется и на строки. Так что просто добавляем или к while. - person aatrujillob; 03.12.2011
comment
Спасибо! Это очень полезно. - person Laura; 03.12.2011