dplyr sample_n其中n是分组变量的值

AJP*_*123 6 r dplyr

我有以下分组数据框,我想使用该函数dplyr::sample_n从每个组的数据框中提取行.我想使用NDG每个组中的分组变量的值作为从每个组中提取的行数.

> dg.tmp <- structure(list(Gene = c("CAMK1", "GHRL", "TIMP4", "CAMK1", "GHRL", 
"TIMP4", "ARL8B", "ARPC4", "SEC13", "ARL8B", "ARPC4", "SEC13"
), GLB = c(3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10), NDG = c(1, 
1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -12L), .Names = c("Gene", "GLB", 
"NDG"))

> dg <- dg.tmp %>% 
     dplyr::group_by(GLB,NDG)

> dg
Source: local data frame [12 x 3]
Groups: GLB, NDG

      Gene GLB NDG
1    A4GNT   3   1
2    ABTB1   3   1
3     AHSG   3   1
4    A4GNT   3   2
5    ABTB1   3   2
6     AHSG   3   2
7    AADAC  10   1
8  ABHD14B  10   1
9   ACVR2B  10   1
10   AADAC  10   2
11 ABHD14B  10   2
12  ACVR2B  10   2
Run Code Online (Sandbox Code Playgroud)

例如,假设正确的随机选择,我想要代码

> dg %>% dplyr::sample_n(NDG)
Run Code Online (Sandbox Code Playgroud)

输出:

Source: local data frame [6 x 3]
Groups: GLB, NDG

      Gene GLB NDG
1    A4GNT   3   1
2    A4GNT   3   2
3    ABTB1   3   2
4    AADAC  10   1
5    AADAC  10   2
6  ABHD14B  10   2
Run Code Online (Sandbox Code Playgroud)

但是,它会出现以下错误:

Error in eval(expr, envir, enclos) : object 'NDG' not found
Run Code Online (Sandbox Code Playgroud)

通过比较,dplyr::slice在我使用代码时给出正确的输出

> dg %>% dplyr::slice(1:unique(NDG))
Run Code Online (Sandbox Code Playgroud)

用稍有hackish的unique在这方面,但是,代码

> dg %>% dplyr::slice(1:NDG)
Run Code Online (Sandbox Code Playgroud)

返回以下警告消息

Warning messages:
1: In slice_impl(.data, dots) :
  numerical expression has 3 elements: only the first used
2: In slice_impl(.data, dots) :
  numerical expression has 3 elements: only the first used
3: In slice_impl(.data, dots) :
  numerical expression has 3 elements: only the first used
4: In slice_impl(.data, dots) :
  numerical expression has 3 elements: only the first used
Run Code Online (Sandbox Code Playgroud)

显然是因为NDG正在评估(在适当的环境中)c(1,1,1)c(2,2,2),因此1:NDG返回上述警告.


关于为什么我得到错误,我知道Hadley用于方法sample_n.grouped_df的代码是

sample_n.grouped_df <- 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")
  sampled <- lapply(index, sample_group, frac = FALSE,
    tbl = tbl, size = size, replace = replace, weight = weight, .env = .env)
  idx <- unlist(sampled) + 1

  grouped_df(tbl[idx, , drop = FALSE], vars = groups(tbl))
}
Run Code Online (Sandbox Code Playgroud)

可以在相关的Github页面上找到.因此我得到错误,因为sample_n.grouped_df找不到变量NGD因为它没有在正确的环境中查找.

因此,有没有使用的一种巧妙的方法sample_ndg,以获得

Source: local data frame [6 x 3]
Groups: GLB, NDG

      Gene GLB NDG
1    A4GNT   3   1
2    A4GNT   3   2
3    ABTB1   3   2
4    AADAC  10   1
5    AADAC  10   2
6  ABHD14B  10   2
Run Code Online (Sandbox Code Playgroud)

通过对每组使用随机抽样?

小智 4

一个可能的答案,但我不相信这是最佳答案:用(和 1 的一小部分)排列数据帧的行dplyr::sample_frac,然后切片所需的行数:

> set.seed(1)
> dg %>% 
      dplyr::sample_frac(1) %>%
      dplyr::slice(1:unique(NDG))
Run Code Online (Sandbox Code Playgroud)

这给出了正确的输出。

Source: local data frame [6 x 3]
Groups: GLB, NDG

    Gene GLB NDG
1  A4GNT   3   1
2   AHSG   3   2
3  A4GNT   3   2
4 ACVR2B  10   1
5  AADAC  10   2
6 ACVR2B  10   2
Run Code Online (Sandbox Code Playgroud)

我想如果有必要的话我可以编写一个函数来在一行中完成此操作。