用R中的循环重采样

时间:2018-08-02 11:39:42

标签: r loops resampling

请考虑以下数据:

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

所以我有4个观察结果。

现在,我想从2中随机选择两次d个观测值(无重复)。对于这两次,我想计算以下内容:

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

也就是说,我将得到两个数字,我想计算它们的平均值。有人可以通过 R 中的循环功能演示如何做到这一点吗?

示例:

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

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)

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

1 个答案:

答案 0 :(得分:1)

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

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