【问题标题】:R: Sample into bins of predefined sizes (partition sample vector)R:样本到预定义大小的箱中(分区样本向量)
【发布时间】:2012-07-02 11:07:41
【问题描述】:

我正在处理一个数据集,该数据集由 ~10^6 个值组成,这些值聚集到可变数量的 bin 中。在我的分析过程中,我试图随机化我的聚类,但保持 bin 大小不变。作为一个玩具示例(在伪代码中),这看起来像这样:

data <- list(c(1,5,6,3), c(2,4,7,8), c(9), c(10,11,15), c(12,13,14));
sizes <- lapply(data, length);
for (rand in 1:no.of.randomizations) {
    rand.data <- partition.sample(seq(1,15), partitions=sizes, replace=F)
}

所以,我正在寻找一个像“partition.sample”这样的函数,它将采用一个向量(如 seq(1,15))并从中随机采样,返回一个列表,其中的数据被划分为给定的正确 bin 大小已经按“尺寸”了。

我一直在尝试自己编写一个这样的函数,因为这项任务似乎并不难。但是,将向量划分为给定的 bin 大小看起来如果“在后台”完成会更快、更有效,这意味着可能不在本机 R 中。所以我想知道我是否只是错过了适当的名称功能,或者是否有人可以向我指出一个聪明的解决方案:-)

非常感谢您的帮助和时间! :-)

最好的,

莱蒙

更新

“no.of.randomizations”是指我运行整个“随机化循环”的实际次数。稍后,这显然会包括比实际采样更多的步骤。

此外,我还对实现上述壮举的技巧感兴趣无需替换。

提前致谢,非常感谢您的帮助!

【问题讨论】:

  • 您的“no.of.randomizations”的预期值(和目的)非常模糊。
  • 是的,我明白了。事实上,我只是指“随机化次数”,即我通过 for 循环运行多少次以执行任何计算(包括“partition.sample”步骤)。很抱歉!

标签: r vector sample data-partitioning


【解决方案1】:

修订:这应该是相当有效的。它的复杂性应该主要在排列步骤:

# A single step:
x <- sample( unlist(data)) 
list( one=x[1:4], two=x[5:8], three=x[9], four=x[10:12], five=x[13:16]) 

如上所述,“no.of.randomizations”可能是此过程的重复应用次数,在这种情况下,您可能需要将replicate 包裹起来:

replic <- replicate(n=4, { x <- sample(unlist(data))
   list( x[1:4], x[5:8], x[9], x[10:12], x[13:15]) }  )

【讨论】:

  • 感谢 DWin 的回答!这非常适合 with 替换采样。但是是否还有一个调整可以在不替换的情况下完成它?很抱歉在最初的问题中没有明确这一点......
  • 我不明白,默认是sample工作without_replacement,所以这就是当前的行为。
  • 是的。但我想找到原始“数据”向量的独特排列,划分为“大小”给定大小的向量。在您的解决方案中,我得到五个子向量,每个子向量均未经替换进行采样。但是,跨向量存在重复项。我可能没有足够的经验在第一次尝试中充分表达问题 - 对此我感到抱歉!无论如何,我想我已经找到了一个合理的解决方案,同时也基于你的回答。 (见下文)
  • 啊,完美。非常感谢这个建议! :-)
【解决方案2】:

经过一番思考和谷歌搜索,我想出了一个可行的解决方案。但是,我仍然不相信这是最快、最有效的方法。

原则上,我可以生成一个“数据”的唯一排列的长向量,然后通过提供给拆分的 factor 参数将其拆分为长度为“大小”的向量列表.为此,我需要为我的不同“数据”组提供一个额外的 ID 方案,而我恰好有这个方案。

看代码就更清楚了:

data <- list(c(1,5,6,3), c(2,4,7,8), c(9), c(10,11,15), c(12,13,14));
sizes <- lapply(data, length);

到目前为止,一切如上

names <- c("set1", "set2", "set3", "set4", "set5");

就我而言,我很幸运已经从数据中提供了“名称”。否则,我将不得不将它们作为(例如)

names <- seq(1, length(data));

然后可以使用 rep 将这个“名称”向量扩展为“大小”:

cut.by <- rep(names, times = sizes);
[1] 1 1 1 1 2 2 2 2 3 4 4 4 5
[14] 5 5

然后可以将这个新向量“cut.by”作为参数提供给 split()

rand.data <- split(sample(1:15, 15), cut.by)
$`1`
[1]  8  9 14  4
$`2`
[1] 10  2 15 13
$`3`
[1] 12
$`4`
[1] 11  3  5
$`5`
[1] 7 6 1

这完成了我一直在寻找的工作。它从背景“1:15”中采样,并通过向量“cut.by”将结果拆分为长度为“sizes”的向量。

但是,我仍然不乐意通过额外的(可能)长向量来指示拆分位置,例如上面代码中的“cut.by”。这绝对有效,但对于非常长的数据向量,我猜它可能会变得很慢。

无论如何,感谢您提供的答案和指导!非常感谢您的帮助:-)

【讨论】:

    猜你喜欢
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多