【问题标题】:R Weighted Sampling ProceduresR加权抽样程序
【发布时间】:2020-04-03 18:23:35
【问题描述】:
data1=data.frame("School"=c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5),
"Group"=c(1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,2,2,2),
"Class"=c('A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A','B','C','A','B','C'),
"Size"=c(459,441,410,201,327,156,129,427,249,331,477,458,288,472,275,449,424,469,386,387,103,320,284,277,481,167,348,247,115,193))

data2=data.frame("ID"=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30),
"Group"=c(2,2,2,2,1,1,1,2,2,2,2,2,2,1,1,2,1,2,1,1,2,2,2,2,2,1,1,1,1,1),
"Class"=c('A','B','C','B','C','C','A','A','A','B','B','A','B','A','C','C','B','A','B','A','B','C','B','A','C','B','B','C','C','B'),
"Funds"=c(5,8,9,4,6,3,5,7,6,7,6,7,6,7,6,7,4,9,5,7,5,5,5,7,9,7,6,9,4,7),
"Ratio"=c(2,2,3,1,1,2,3,3,1,3,3,3,3,1,1,3,2,1,1,1,3,1,3,3,1,2,1,3,1,3),
"WEIGHT"=c(162,65,104,118,105,49,107,93,25,24,103,115,64,186,57,123,86,181,70,111,154,135,37,73,127,148,188,169,73,52))

我有data1和data2,希望提供一个简单的例子。

在 data1 中,您可以看到 'Group' X 'Class' 组合的 'School' 编号和 'Size'。 在 data2 中,您有关于每个“组”X“类”组合的“基金”和“比率”的信息。在 data2 中,您还具有等于采样帧的 'WEIGHT',也就是说,不同的 'ID' 具有不同的“权重”或重要性。

我希望创建如下所示的 data3:

总的来说,我希望 data3 有 sum(data1$Size) 行。我希望从 data1 复制每个“学校”X“组”X“班级”组合的“大小”行。然后我希望从data2中用'Group' X 'Class' 'Funds'和'Ratio'替换样本,使用WEIGHTS来告知选择每一行的概率,以填写data3。

【问题讨论】:

  • @joran ........
  • 如果您对 data1 中的“大小”列求和,这将为您提供预期的输出行数。
  • Group 和 Class 是两个数据集中相交的列名,但它们也是重复的。所以,不清楚你想如何合并
  • @akrun 非常感谢。我认为我在解释这一点时遇到了挑战,但我会继续努力。第 1 步是通过“data1”制作“data3”并通过“Size”扩展它。例如,第一行重复 459 次,第二行重复 441 次,以此类推。然后将空列“Funds”和“Ratio”添加到“data3”。完成后,从 'Group' 和 'Class' 中的 'Funds' 和 'Ratio' 中采样,使用 WEIGHTS 在 'data3' 中填写 'Funds' 和 'Ratio' 的值
  • 我根据“大小”列扩展了 data1,然后按“组”、“类”拆分两个数据集,并使用 Map 根据创建的概率在第一个数据集中创建列'WEIGHTS/总和(WEIGHTS)

标签: r data.table sample


【解决方案1】:

这是data.table 的一个选项,我们根据“大小”列扩展数据1,然后按“组”、“类”拆分两个数据集,并使用 Map 根据概率在第一个数据集中创建列使用WEIGHT/sum(WEIGHT) 创建,用于在sample 中对“资金”、“比率”列值进行采样,分配(:=)以在list 中创建新列,最后在rbind @987654327 中创建新列@rbindlist`

library(data.table)
dt1 <- setDT(data1)[rep(seq_len(nrow(data1)), Size)]
lst1 <- split(dt1, dt1[, .(Group, Class)])
lst2 <- split(data2, data2[c('Group', 'Class')], drop = TRUE)

out <- rbindlist(Map(function(x, y) {
            prb = y$WEIGHT/sum(y$WEIGHT)
            x[, c('Funds', 'Ratio') := 
           .(sample(y$Funds,  size = .N, replace = TRUE, prob=prb), 
            sample(y$Ratio,  size = .N, replace = TRUE, prob=prb) )]}, 
            lst1, lst2[names(lst1)]))

out[, Size := NULL]
sum(data1$Size)
#[1] 9750
nrow(out)
#[1] 9750

【讨论】:

  • 我认为这很完美,我现在将尝试使用我的真实、混乱的数据
  • 非常感谢。它让我等待接受它。我收到一个错误... > lst2 [.data.table(data2, c("Group", "Class" )) :当 i 是 data.table(或字符向量)时,必须使用 'on=' 参数(参见 ?data.table)指定要连接的列,通过键入 x(即已排序,并且标记为已排序, 参见 ?setkey), 或者通过在 x 和 i 之间共享列名(即自然连接)。由于 x 在 RAM 中排序,键控连接可能对非常大的数据有进一步的速度优势。
  • @bvowe 在我的示例中,data2 不是 data.table。如果你有一个data.table,那么使用split(data2, data2[, .(Group,Class)])
  • @bvowe 谢谢。您的其他问题解决方案是否有效
  • 我不知道这是否合适,但如果您可以进行简短的聊天,我很乐意为您提供短期的付费咨询
猜你喜欢
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多