以不同的概率重复采样

时间:2013-12-11 01:09:33

标签: r

在以下代码"重量"是一个庞大的权重集矩阵。该矩阵由1000行和4列组成。每行是一组权重(每行中元素的总和等于1)。

另外,有四个对象,我想根据每个权重集选择其中一个。换句话说,应该对所有权重集重复这种随机选择。

现在我已用for解决了问题。但是有没有更有效的方法在R中编码呢?

y <- c("a", "b", "c", "d")
for(i in 1:nrow(Weight)){
  selection[i] <- sample(y, 1, prob=Weight[i,]) #selection is a vector with the same number of rows as Weight
}

2 个答案:

答案 0 :(得分:5)

更有效的方法是首先计算权重的行方式累积总和,然后在01之间绘制一个数字,并查看它在该累积总和中的位置。这样,您只需要对runif进行一次调用即可获得随机数据,而使用其他方法进行1000调用。

Weight <- matrix(sample(1:100, 1000 * 4, TRUE), 1000, 4)

x <- runif(nrow(Weight))
cumul.w <- Weight %*% upper.tri(diag(ncol(Weight)), diag = TRUE) / rowSums(Weight)
i <- rowSums(x > cumul.w) + 1L
selection <- y[i]

另请注意我是如何通过乘以三角矩阵而不是使用较慢的apply(Weight, 1, cumsum)来计算累积和。一切都是矢量化的,所以它应该比使用applyfor循环更快。


applyfor进行基准比较:

f_runif <- function(Weight, y) {
  x <- runif(nrow(Weight))
  cumul.w <- Weight %*% upper.tri(diag(ncol(Weight)), diag = TRUE) /
    rowSums(Weight)
  i <- rowSums(x > cumul.w) + 1L
  y[i]
}

f_for <- function(Weight, y) {
  selection <- rep(NA, nrow(Weight))
  for(i in 1:nrow(Weight)){
    selection[i] <- sample(y, 1, prob=Weight[i,])
  }
}

f_apply <- function(Weight, y) {
  apply(Weight, 1, function(w)sample(y, 1, prob=w))
}

y <- c("a", "b", "c", "d")
Weight <- matrix(sample(1:100, 1000 * 4, TRUE), 1000, 4)

library(microbenchmark)
microbenchmark(f_runif(Weight, y),
               f_for  (Weight, y),
               f_apply(Weight, y))

# Unit: microseconds
#                expr       min        lq    median         uq       max neval
#  f_runif(Weight, y)   223.635   231.111   274.531   281.2165  1443.208   100
#    f_for(Weight, y) 10220.674 11238.660 11574.039 11917.1610 14583.028   100
#  f_apply(Weight, y)  9006.974 10016.747 10509.150 10879.9245 27060.189   100

答案 1 :(得分:2)

sample包装到一个只允许传递一个参数的函数中,一行来自Weight

myfun <- function(w) {
    sample(y, 1, prob=w)
}

然后您可以使用其中一个申请系列:

apply(Weight, 1, myfun)

但是,只要您预先分配selection,您的方法效率就不会非常低。