R无需替换即可复制样本功能

Posted

技术标签:

【中文标题】R无需替换即可复制样本功能【英文标题】:R replicate sample function without replacement 【发布时间】:2016-05-24 19:34:45 【问题描述】:

我想对 5 个随机行进行 1000 次抽样并将它们汇总到一个数据框中。我对replace = FALSE 有疑问,我想知道将它放在哪里replace = TRUE

我有一个包含 5,000 行的数据集,看起来(简化)如下:

 Fund.ID Vintage Type Region.Focus Net.Multiple  Size
[1,] 4716  2003  2    US           1.02          Small
[2,] 2237  1998  25   Europe       0.03          Medium
[3,] 1110  1992  2    Europe       1.84          Medium
[4,] 12122 1997  25   Asia         2.04          Large 
[5,] 5721  2006  25   US           0.86          Mega
[6,] 730   1998  2    Europe       0.97          Small

这是我的函数,它从一个随机行开始,并包含对正在绘制的 5 行的约束。:

       simulate <- function(inv.period) 
          start <- sample_n(dataset, 1, replace=TRUE) #draw random first fund
          t <- start$Vintage:(start$Vintage + inv.period) #define investment period contingent on first fund
          fof <- dataset[sample(which(dataset$Vintage %in% t), 5, replace = FALSE), ] #include constraint, 5 funds in portfolio
        

#replicate this function 1,000 times 
#and give out as a data frame with portfolios classified
        library(plyr)
        library(dplyr)
        fof.5 <- rdply(1000, simulate(4))
        rename(fof.5, FoF.ID = .n)

如果我在模拟函数中使用replace=FALSE(在fof

sample.int(length(x), size, replace, prob) 中的错误: 'replace = FALSE' 时不能抽取大于总体的样本 如果我输入replace = TRUE,整个表达式都有效。但是,这是不正确的,因为在同一个样本中可能会绘制两次行,这是我不希望的。

有没有办法在绘制行时放置replace=FALSE,但为整个数据集放置replace=TRUE?应该是:一行只能在样本中绘制一次,但可以在另一个样本中再次绘制。

【问题讨论】:

如果您使用包中的函数,请用library(package) 注明它可以帮助其他人复制您的代码并找到解决方案。 函数simulate不返回任何值。只要t 的长度小于5,它也会失败。例如,假设start 从其样本中返回第 4 行。那么start$Vintage 将是1997。现在假设 inv.period 是 1。正在采样两个值,第 2 行和第 4 行。您要求提取 5 个值而不进行替换。这没有意义。 我正在使用 plyr 和 dplyr 包,如第二个代码框中所示。确实,我的模拟函数没有返回任何值。那是因为我将复制的函数输出存储为带有 rdply 函数的数据帧。由于我有一个 1982-2015 年的大型数据集(5,000 行),因此您提出的第二点应该不会导致问题。 fof.5 你觉得sample_n(dataset, 1, replace=TRUE)sample_n(dataset, 1, replace=FALSE)有什么区别? 【参考方案1】:

我建议取出dplyr 的东西,没有必要。其次,为匹配添加一个名为 matches 的变量,然后对该向量的长度或数字 5 进行采样,以较小者为准。最后,我会使用data.table::rbindlist,它有一个参数来创建一个索引来指示进行了哪次绘制。输出会是一个data.table,如果你不熟悉,可以在最后使用as.data.frame(rbindlist(....)),将其转回data.frame。:

library(data.table)
simulate <- function(inv.period) 
  start <- dataset[sample(nrow(dataset), 1, replace=TRUE),]
  t <- start$Vintage:(start$Vintage + inv.period)
  matches <- which(dataset$Vintage %in% t)
  dataset[sample(matches, min(length(matches),5), replace = FALSE), ]


r <- replicate(1000, simulate(5), simplify=FALSE)
rbindlist(r, idcol="draw")

【讨论】:

谢谢!这完美无缺。我在末尾添加了 as.data.frame() 表达式,现在我有了一个我想要的数据框。 当我运行函数时,例如对于 5 年的投资期和样本中的 15、25、30 甚至 100 行,该功能无法正常工作:一些样本的行数少于指定的行数(例如 2 而不是 50),而其他样本有指定的行数。我确实意识到这是由于我多年来的行数有限(并且开始不受限制)我该如何解决这个问题?我可以以某种方式在第一个开始示例中设置约束吗? 您无法提取不存在的内容。没有代码可以为您创建更多数据,您必须使用现有的数据。 我知道数据集有点太小了。然而,这里的问题更多是which()min(lenght(matches)) 表达式不够严格。如果我只模拟几个样本,就会出现同样的问题。因此,可以通过更改第一个开始表达式来解决问题(例如,使用which() 函数来识别如果所需样本很大,那么它应该只获取 1996 年之后的数据(那是我有更多行的时候)。

以上是关于R无需替换即可复制样本功能的主要内容,如果未能解决你的问题,请参考以下文章

列出样本空间?

三角分布的随机样本:R

R(和 dplyr?) - 按组从数据帧中采样,最大样本大小为 n

在 R 中复制不替换的分层随机抽样

简单高效性能好SetFit:无需Prompts的高效小样本学习

简单高效性能好SetFit:无需Prompts的高效小样本学习