【问题标题】:R Sampling with proportions based on labels in the dataR 基于数据中标签的比例采样
【发布时间】:2020-11-18 16:53:06
【问题描述】:

我正在尝试使用特定逻辑对我的数据集进行采样。 我想为每个标记的 id 用某些部分对我的数据进行采样。我想知道R中的sample()函数中是否有这种类型的选项

我的数据集的简单描述是:

       id mode OD_ID
1:  50909    1     1
2:  62024    1     1
3:  82812    1     1
4: 100593    1     1
5: 150391    2     1
6: 159413    2     1
7: 132134    2     1
8: 111111    2     1
9:  78524    3     1
10:802212    3     1
   .
   .
   .

我想在同一 id 列“OD_ID”中以一定比例的列“mode”对这些数据进行采样

例如,我想对列 OD_ID=1 的数据进行采样,“模式”的比例不同

我想要 mode=1 71% mode=2 21% 和 mode=3 8% 的采样数据集。 我有更多行数足够的数据,我希望采样数据集的每个 OD_ID 有 10 个数据。我还想将样本的列数四舍五入到最接近的整数。

所以我的输出的一个例子是

      id mode OD_ID
  some id    1     1
  some id    1     1
  some id    1     1
  some id    1     1
  some id    1     1
  some id    1     1
  some id    1     1
  some id    2     1
  some id    2     1
  some id    1     1
   .
   .
   .
  some id    1     2
   .
   .
   .

对于每对 OD_ID,模式 1 的 71% 模式 2 的 21% 模式 3 的 8% 的采样数据

我将不胜感激。

【问题讨论】:

  • 您的样本量是否不同?在您的示例中,样本大小为 10。如果跨组始终为 10,那么您将始终获得 7 模式 1、2 模式 2 和 1 模式 3。为什么不只对模式 7、2 和 1 个项目进行采样分别是 1、2 和 3?
  • @ekoam 每个标记为“OD_ID”的样本量不同

标签: r dataframe random sample


【解决方案1】:

考虑这个函数

sample_p <- function(lab, n, p) {
  stopifnot(sum(p) == 1)
  p <- p[as.character(unique(lab))]
  p <- p / sum(p)
  sizes <- round(n * p)
  unlist(lapply(names(sizes), function(nm, x, s) {
    sample(x[[nm]], s[[nm]])
  }, split(seq_along(lab), lab), sizes))
}

然后你可以做这样的事情

library(dplyr)
df %>% 
  group_by(OD_ID) %>% 
  slice(sample_p(.data$mode, 10, c(`1` = 0.71, `2` = 0.21, `3` = 0.08)))

以这个数据框为例

set.seed(2020)
df <- data.frame(
  id = sample.int(1e6, 200), 
  mode = sample(c(1, 2, 3), 200, T), 
  OD_ID = rep(c(1, 2), each = 100)
)

输出如下所示

# A tibble: 20 x 3
# Groups:   OD_ID [2]
       id  mode OD_ID
    <int> <dbl> <dbl>
 1 779894     3     1
 2 797304     2     1
 3 210680     2     1
 4 753704     1     1
 5 503423     1     1
 6 645002     1     1
 7  27814     1     1
 8 334087     1     1
 9 922379     1     1
10 330177     1     1
11 757881     3     2
12 712945     1     2
13 312035     1     2
14 760862     1     2
15 553939     1     2
16 119729     1     2
17 336224     1     2
18 828775     1     2
19 425781     2     2
20 339844     2     2

【讨论】:

  • 感谢您的帮助!!虽然在我的情况下它返回一个错误 Error in grp_n[[as.character(cur_group()$OD_ID)]] : subscript out of bounds
  • 你修改过这个grp_n &lt;- c(`1` = 10, `2` = 20)吗?请注意,您需要为每个 OD_ID 指定样本大小。
  • 我总共有 1088 个 OD_ID,我将它们放在一个数据框中。如果我想为每个 1088 个 OD_ID 提供相同数量的样本,我将如何在函数中编写它?
  • 但是您说您的样本量因每个 OD_ID 而异。这就是我写这个函数的原因。如果 OD_ID 的样本量相同,那么您需要不同的函数。 @YunHyunsoo
  • 我为错误的问题道歉。如何为每 1088 个 OD_ID 分配样本?
猜你喜欢
  • 1970-01-01
  • 2020-02-12
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多