【问题标题】:Generate random numbers by group with replacement按组生成随机数并替换
【发布时间】:2016-10-10 14:26:33
【问题描述】:

** 编辑是因为我是个傻瓜 - 有替换,而不是没有 **

我有一个包含 421 个组的大型(>500k 行)数据集,由两个分组变量定义。样本数据如下:

df<-data.frame(group_one=rep((0:9),26), group_two=rep((letters),10))

head(df)

  group_one group_two
1         0         a
2         1         b
3         2         c
4         3         d
5         4         e
6         5         f

...等等。

我想要的是一些分层样本的数量(目前 k = 12,但该数量可能会有所不同),通过 (group_one x group_two) 的成员资格。每个组中的成员资格应由一个新列 sample_membership 指示,该列的值从 1 到 k(同样,目前为 12)。我应该能够按 sample_membership 进行子集化,并获得多达 12 个不同的样本,在考虑 group_one 和 group_two 时,每个样本都具有代表性。

因此,最终数据集看起来像这样:

  group_one group_two sample_membership
1         0         a                 1  
2         0         a                12
3         0         a                 5
4         1         a                 5
5         1         a                 7
6         1         a                 9

想法?提前非常感谢!

【问题讨论】:

  • 您的标题说“无需替换”,但您的问题没有提及。您是否想要无替换抽样(并且您保证每个分组
  • 这是一个错误。绝对应该有替换。很抱歉给您带来了困惑。
  • 随时编辑您的问题标题以更正错误。

标签: r random sample


【解决方案1】:

使用dplyr 的未经测试的示例,如果它不起作用,它可能会为您指明正确的方向。

library( dplyr )
set.seed(123)
df <- data.frame(
  group_one = as.integer( runif( 1000, 1, 6) ),
  group_two = sample( LETTERS[1:6], 1000, TRUE)
) %>%
  group_by( group_one, group_two ) %>%
  mutate(
    sample_membership = sample( seq(1, length(group_one) ), length(group_one), FALSE)
  )

祝你好运!

【讨论】:

  • 仅供参考,您可以使用dplyr::n() 代替length(group_one),这样可以节省一点打字时间。
  • 谢谢,虽然这是从 1 到 (group_one x group_two) 中的项目数的随机分布,并且不会在 12 达到峰值。我想知道我是否可以划分每个项目的数量按 12 分组并舍入/截断。我会考虑。再次感谢!
【解决方案2】:

可能是这样的?:

library(dplyr)
  df %>% 
    group_by(group_one, group_two) %>% 
    mutate(sample_membership = sample(1:12, n(), replace = FALSE))

【讨论】:

    【解决方案3】:

    这是一个基本的 R 方法,它假定您的 data.frame 是按组排序的:

    # get number of observations for each group
    groupCnt <- with(df, aggregate(group_one, list(group_one, group_two), FUN=length))$x
    
    # for reproducibility, set the seed
    set.seed(1234)    
    # get sample by group
    df$sample <- c(sapply(groupCnt, function(i) sample(12, i, replace=TRUE)))
    

    【讨论】:

    • 这很好,但似乎有一些 (group_one x group_two) 组合的成员为零,因此 groupCnt 以一些 NA 结束。如果我为这些 NA 交换零,最终 df$sample 的行数比 df 少,因此失败。想法?
    • 它似乎适用于您的示例。你能提供一个发生这种情况的data.frame吗? aggregate 创建一个仅包含组 1 和组 2 组合的 data.frame。由于 groupCnt 是使用 length 函数构造的,因此它不应该产生 NA。
    • 一种可能性是原始数据中每组的观测值超过 12 个。如果是这种情况,您必须将样本限制在前 12 个(或随机选择的 12 个),在每组内进行替换抽样,或者将 k 增加到每组的最大数量以上。
    • 我每组确实有超过 12 个,而且我确实需要更换样品 - 我的错误在标题中。我很抱歉。
    • @seehuus 我已经编辑了我的答案以反映带替换的抽样。请考虑按照上面 gregor 的建议编辑您的问题。
    【解决方案4】:

    这是一种单行的data.table 方法,如果你有一个很长的data.frame,你绝对应该考虑一下。

    library(data.table)
    
    setDT(df)
    
    df[, sample_membership := sample.int(12, .N, replace=TRUE), keyby = .(group_one, group_two)]
    
    df
    #    group_one group_two sample_membership
    #   1:         0         a                 9
    #   2:         0         a                 8
    #   3:         0         c                10
    #   4:         0         c                 4
    #   5:         0         e                 9
    # ---                                      
    # 256:         9         v                 4
    # 257:         9         x                 7
    # 258:         9         x                11
    # 259:         9         z                 3
    # 260:         9         z                 8
    

    对于没有替换的抽样,请使用replace=FALSE,但如其他地方所述,请确保每个组的成员少于 k 个。 或:

    如果您想使用“不进行不必要替换的抽样”(编造这个——不确定这里的正确术语是什么),因为每个组的成员超过 k 个,但仍想保留组的大小尽可能均匀,您可以执行以下操作:

    # example with bigger groups
    k <- 12L
    big_df <- data.frame(group_one=rep((0:9),260), group_two=rep((letters),100))
    setDT(big_df)
    
    big_df[, sample_round := rep(1:.N, each=k, length.out=.N), keyby = .(group_one, group_two)]
    big_df[, sample_membership := sample.int(k, .N, replace=FALSE), keyby = .(group_one, group_two, sample_round)]
    head(big_df, 15) # you can see first repeat does not occur until row k+1 
    

    在每个“抽样轮次”(组中的前 k 个观察值,组中的第二个 k 观察值等)中,都会进行无替换抽样。然后,如有必要,下一轮抽样会使所有 k 个分配再次可用。

    这种方法确实可以对样本进行均匀分层(但只有在每个组中有多个 k 个成员时才可能实现完全均匀)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-19
      相关资源
      最近更新 更多