2016-11-18 120 views
1

我有一個矩陣Q,它的維數相對較高(100X500000),我想對它進行下采樣。通過縮減範例,我會用一個例子來解釋。向下採樣R中的矩陣

設Q =

1 4 9 
3 2 1 

和下采樣大小= N。我想從一個總和(Q)= 20球的球中抽出n個球,每個球以6種方式中的1種對應於矩陣的不同索引對。就像我有1個A球,4個B球等球,而且我正在畫n個球而沒有更換。

我希望它以矩陣的形式返回。一個實例中的返回值,例如,下采樣(Q,3)=

0 0 2 
1 0 0 

我的方法試圖使用樣品:

sample(length(as.vector(Q)), size=n, replace=FALSE, prob = as.vector(Q)) 

然而與此問題,樣品認爲1:長度( as.vector(Q))和我所有的球一樣,所以我不能抽出更多的長度(as.vector(Q))球,因爲我沒有取代我的球。

那麼爲了適應我的方法,我需要通過從這個向量中減去1來更新我的概率,並使用某種for循環來逐個調用示例。這聽起來不像代碼漂亮。

有沒有更好的方式來做到這一點在R友好,沒有for循環的方式?

回答

6

這有點低效,但如果sum(Q)不是也可以大,你可以通過分解/複製矢量然後採樣然後重新聚集/製表來完成。

Q <- setNames(c(1,4,9,3,2,1),LETTERS[1:6]) 
n <- 10 
set.seed(101) 
s0 <- sample(rep(names(Q),Q), 
     size=n,replace=FALSE) 
Q2 <- table(factor(s0,levels=names(Q))) 
## A B C D E F 
## 1 2 5 1 0 1 

我不確定你的矩陣結構。您可以使用dim(Q2) <- dim(Q)以與原始矩陣相同的順序重新組織結果...

+0

太好了,我會試試看。 Fyi我將無法使用維度的信件b/c,但我只是使用names = [1:length(as.vector(Q)] – lynnyi

3

下面是一種非常好的方法。您可以通過which(x <= cq)[1]替代finding the first TRUE value的特殊功能來提高其效率(如有必要)。

Q = matrix(c(1, 4, 9, 3, 2, 1), nrow = 2) 

set.seed(47) 
samp = sample(sum(Q), size = 3) 
cq = cumsum(Q) 

inds = table(sapply(samp, function(x) which(x <= cq)[1])) 

result = integer(length(Q)) 
result[as.integer(names(inds))] = inds 
dim(result) = dim(Q) 
#  [,1] [,2] [,3] 
# [1,] 0 2 0 
# [2,] 0 0 1