Dplyr sample_n, where n is the value of the grouped variable

I have the following grouped data frame, and I would like to use a function dplyr::sample_nto extract rows from this data frame for each group. I want to use the value of a grouped variable NDGin each group as the number of rows to extract from each group.

> 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

For example, assuming the right random choice, I want the code

> dg %>% dplyr::sample_n(NDG)

for output:

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

However, it gives the following error:

Error in eval(expr, envir, enclos) : object 'NDG' not found

For comparison, dplyr::sliceit gives the correct output when I use the code

> dg %>% dplyr::slice(1:unique(NDG))

In this context, it is a bit hacked unique, however using code

> dg %>% dplyr::slice(1:NDG)

returns the following warning messages

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

NDG ( ) c(1,1,1) c(2,2,2), , , 1:NDG .


, , , , 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))
}

Github. , , sample_n.grouped_df NGD, .

, sample_n dg

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

?

+4
3

, , : dplyr::sample_frac ( 1), :

> set.seed(1)
> dg %>% 
      dplyr::sample_frac(1) %>%
      dplyr::slice(1:unique(NDG))

.

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

, , , .

+3

, :

dg %>% 
  sample_frac(1) %>%
  filter(row_number() <= NDG) %>%
  arrange(NDG)

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

     Gene GLB NDG
1    AHSG   3   1
2   ABTB1   3   2
3    AHSG   3   2
4 ABHD14B  10   1
5   AADAC  10   2
6 ABHD14B  10   2

sample_frac , NDG. arrange , , .

+2

I ran into the same problem using grouped dfs, and remembered there is a very elegant way to do this in purrr, as described in this very useful tutorial :

library(purrr)

dg.tmp %>% 
  nest(-GLB, -NDG) %>% 
  mutate(data = map2(data, NDG, sample_n)) %>% 
  unnest

One of the advantages is that it does not require the permutation of ALL rows of data, as with sample_frac, which can be quite expensive with a large data framework.

0
source

All Articles