【问题标题】:dplyr: Sample size greater than population sizedplyr:样本大小大于总体大小
【发布时间】:2016-02-11 07:13:32
【问题描述】:

我有一个数据框:

> class(dataset)
[1] "grouped_df" "tbl_df"     "tbl"        "data.frame"
> dim(dataset)
[1] 64480    39

我想从中采样 50.000 个样本

> dataset %>% dplyr::sample_n(50000)

但一直给我错误

错误:样本大小 (50000) 大于总体大小 (1)。是否要替换 = TRUE?

但是例如有效:

> dim(dataset[1] %>% dplyr::sample_n(50000))
[1] 50000     1

那么为什么我的人口规模为(1) - 这与分组有关吗?

【问题讨论】:

  • 请提供一个可重现的例子。 dplyr 输出有关您的数据的错误,因此要回答我们需要查看您的数据的问题(样本或虚构示例)。
  • 这很可能是关于分组的,因为你有"grouped_df"。尝试取消组合并运行相同的代码。
  • 是的,它可能与分组有关。正如您从class(dataset) 的输出中看到的那样,您的数据当前已分组,并且某些组的观察结果可能太少而无法在不替换的情况下对 50000 进行采样。试试dataset %>% ungroup() %>% dplyr::sample_n(50000)
  • 试过了。做到了 !谢谢!

标签: r dplyr


【解决方案1】:

不幸的是,dplyr 不允许您将大型组“抽样”到给定的大小,或者如果它是一个小组,则只使用该组的所有数据 - 您必须将所有数据抽样到最小的组大小,或者抽样最小的与替换组“膨胀”到更大的尺寸。您可以通过如下定义自定义 sample_n 函数来解决此问题:

 ### Custom sampler function to sample min(data, sample) which can't be done with dplyr
 ### it's a modified copy of sample_n.grouped_df
 sample_vals <- function (tbl, size, replace = FALSE, weight = NULL, .env = parent.frame()) 
 {
   #assert_that(is.numeric(size), length(size) == 1, size >= 0)
   weight <- substitute(weight)
   index <- attr(tbl, "indices")
   sizes = sapply(index, function(z) min(length(z), size)) # here's my contribution
   sampled <- lapply(1:length(index), function(i) dplyr:::sample_group(index[[i]],  frac = FALSE, tbl = tbl, 
                                       size = sizes[i], replace = replace, weight = weight, .env = .env))
   idx <- unlist(sampled) + 1
   grouped_df(tbl[idx, , drop = FALSE], vars = groups(tbl))
 }

 samped_data = dataset %>% group_by(something) %>% sample_vals(size = 50000) %>% ungroup()

【讨论】:

  • 如果你使用sample_frac(1)和过滤器可以达到"Sample down" large groups to a given size or just use all of the group's data if it's a small groupstackoverflow.com/questions/30950016/…
  • 哦,很好,但这会强制在采样之前创建一个带有置换行的全新数据框吗?这似乎很贵。
  • 我不知道 :)
  • 或者更简单的方法是 tbl %>% mutate(id = sample(1:n()) %>% filter(id
【解决方案2】:

是的,它可能与分组有关。正如您从class(dataset) 的输出中看到的那样,您的数据当前已分组(注意grouped_df 信息),并且一个或多个组的观察值显然太少,无法在不替换的情况下对 50000 个观察值进行抽样。

要解决此问题,您可以在采样前取消数据分组:

dataset %>% ungroup() %>% sample_n(50000)

或者您可以更换样品:

dataset %>% sample_n(50000, replace = TRUE)

【讨论】:

  • 但是您可以指定对特定值或行的最大值进行采样吗?对非常大的组进行二次采样会很好,但不必重新采样小组即可。
猜你喜欢
  • 2012-04-25
  • 2022-01-14
  • 1970-01-01
  • 2019-05-31
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多