使用 R 中的循环重新采样

Resampling with a loop in R

考虑以下数据:

library(Benchmarking)
d <- data.frame(x1=c(100,200,30,500), x2=c(300,200,10,50), y=c(75,100,3000,400))

所以我有 4 个观察结果。

现在我想从 d 中随机 select 2 观察两次(不重复)。对于这两次中的每一次,我都想计算以下内容:

e <- dea(d[c('x1', 'x2')], d$y)
weighted.mean(eff(e), d$y)

也就是说,我会得到两个数字,我想计算它们的平均值。有人可以展示如何使用 R 中的循环函数执行此操作吗?

示例:

考虑观察 13 是第一次 selected,23 是 selected第二次(当然,这可能会有所不同)。这将给我以下结果:

0.9829268 0.9725806

因为(这里我手动写了观察结果):

> d1 <- data.frame(x1=c(100,30), x2=c(300,10), y=c(75,3000))
> e1 <- dea(d1[c('x1', 'x2')], d1$y)
> weighted.mean(eff(e1), d1$y)
[1] 0.9829268
> 
> d2 <- data.frame(x1=c(200,30), x2=c(200,10), y=c(100,3000))
> e2 <- dea(d2[c('x1', 'x2')], d2$y)
> weighted.mean(eff(e2), d2$y)
[1] 0.9725806

这两个数的平均值是:

0.9777537

我的建议:

我试过:

for (r in 1:2)
{
  a <- (1:4)
  s <- sample(a, 2, replace = FALSE)

  es <- dea([s, c('x1', 'x2')], y[s])
  esav[i] <- weighted.mean(eff(es), y[s])
}
mean(esav)

但这不起作用。有人能帮我吗?

这是一个可能的方法(如果我理解正确的话):

library(Benchmarking)

set.seed(123) # just to reproduce this case

d <- data.frame(x1=c(100,200,30,500), x2=c(300,200,10,50), y=c(75,100,3000,400))
# generate all possible couples of row indexes
allPossibleRowIndexes <- combn(1:nrow(d),2,simplify=FALSE)
# select the first maxcomb couples randomly (without repetition)
maxcomb <- 3 # I chose 3... you can also test all the possibilities
rowIndexesRand <- sample(allPossibleRowIndexes,min(maxcomb,length(allPossibleRowIndexes)))

esav <- NULL
for (rowIdxs in rowIndexesRand){
  es <- dea(d[rowIdxs, c('x1', 'x2')], d$y[rowIdxs])
  esav <- c(esav,weighted.mean(eff(es), d$y[rowIdxs]))
}
avg <- mean(esav)

# or alternatively using sapply instead of loop
avg <- mean(sapply(rowIndexesRand,function(rowIdxs){
  es <- dea(d[rowIdxs, c('x1', 'x2')], d$y[rowIdxs])
  esav <- weighted.mean(eff(es), d$y[rowIdxs])
  return(esav)
}))

结果:

> esav
[1] 0.9829268 0.9725806 0.9058824
> avg
[1] 0.9537966
> rowIndexesRand
[[1]]
[1] 1 3

[[2]]
[1] 2 3

[[3]]
[1] 3 4

编辑:

根据评论,您可以使用以下函数生成唯一的随机索引,而无需生成所有组合。
当然这不是很有效,因为它会多次采样,以防之前已经提取了组合...

# function that (not very efficiently) returns n unique random samples 
# of size=k, taken from the set : 1...size
getRandomSamples <- function(size,k,n){
 # ensure n is <= than the number of combinations
  n <- min(n,choose(size,k))
  env <- new.env()
  for(i in seq_len(n)){
    # sample until it's not a duplicate
    while(TRUE){
      set <- sort(sample.int(size,k))
      key <- paste(set,collapse=',')
      if(is.null(env[[key]])){
        env[[key]] <- set
        break
      }
    }
  }
  unname(as.list(env))
}

# usage example
set.seed(1234) # for reproducibility
getRandomSamples(60,36,5)
[[1]]
 [1]  1  2  4  7  8 10 11 12 13 14 15 16 17 18 20 21 22 23 24 26 30 31 32 33 34 35 36 37 42 43 44 46 47 55 58 59

[[2]]
 [1]  3  4  5  8 10 11 12 13 14 16 17 18 19 20 22 23 24 25 26 29 32 33 35 38 40 43 44 45 47 48 49 50 51 55 56 58

[[3]]
 [1]  1  2  4  5  6  7  8  9 10 11 14 18 19 22 25 27 28 30 36 37 38 39 40 43 46 47 49 50 51 53 54 55 57 58 59 60

[[4]]
 [1]  1  2  5  7  8  9 10 12 13 14 18 19 27 29 30 31 35 36 37 38 42 43 44 46 47 48 49 51 52 53 55 56 57 58 59 60

[[5]]
 [1]  3  5  6  7  9 11 12 13 15 16 19 20 21 22 24 26 27 30 31 32 35 36 37 39 40 42 43 44 45 46 49 50 51 54 55 60