dplyr sample_n 其中 n 是分组变量的值
dplyr sample_n where n is the value of a grouped variable
我有以下分组数据框,我想使用函数 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
例如,假设随机选择正确,我想要代码
> dg %>% dplyr::sample_n(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
但是,它给出了以下错误:
Error in eval(expr, envir, enclos) : object 'NDG' not found
通过比较,dplyr::slice
在我使用代码
时给出了正确的输出
> dg %>% dplyr::slice(1:unique(NDG))
它是在这种情况下使用unique
有点hackish,但是,代码
> dg %>% dplyr::slice(1:NDG)
returns以下警告信息
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
returns 上述警告。
关于我报错的原因,我知道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))
}
里面可以查到相关的Github page。因此我得到了错误,因为 sample_n.grouped_df
找不到变量 NGD
因为它没有在正确的环境中查找。
因此,有没有一种巧妙的方法可以在 dg
上使用 sample_n
来获得
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
通过对每组进行随机抽样?
一个可能的答案,但我不认为这是最佳答案:用 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
而且我想如果有必要,我可以只写一个函数来在一行中执行此操作。
这里有一个备选答案,尽管上面那个看起来不错:
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
除了重新排序您的数据以使其看起来像您想要的输出之外什么都不做。
我 运行 使用分组 dfs 解决了同样的问题,并记得在 purrr
中有一种非常优雅的方法可以做到这一点,如 this very helpful tutorial:
中所述
library(purrr)
dg.tmp %>%
nest(-GLB, -NDG) %>%
mutate(data = map2(data, NDG, sample_n)) %>%
unnest
一个优点是它不需要像 sample_frac
那样对所有数据行进行排列,这对于大型数据帧来说可能非常昂贵。
我有以下分组数据框,我想使用函数 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
例如,假设随机选择正确,我想要代码
> dg %>% dplyr::sample_n(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
但是,它给出了以下错误:
Error in eval(expr, envir, enclos) : object 'NDG' not found
通过比较,dplyr::slice
在我使用代码
> dg %>% dplyr::slice(1:unique(NDG))
它是在这种情况下使用unique
有点hackish,但是,代码
> dg %>% dplyr::slice(1:NDG)
returns以下警告信息
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
returns 上述警告。
关于我报错的原因,我知道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))
}
里面可以查到相关的Github page。因此我得到了错误,因为 sample_n.grouped_df
找不到变量 NGD
因为它没有在正确的环境中查找。
因此,有没有一种巧妙的方法可以在 dg
上使用 sample_n
来获得
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
通过对每组进行随机抽样?
一个可能的答案,但我不认为这是最佳答案:用 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
而且我想如果有必要,我可以只写一个函数来在一行中执行此操作。
这里有一个备选答案,尽管上面那个看起来不错:
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
除了重新排序您的数据以使其看起来像您想要的输出之外什么都不做。
我 运行 使用分组 dfs 解决了同样的问题,并记得在 purrr
中有一种非常优雅的方法可以做到这一点,如 this very helpful tutorial:
library(purrr)
dg.tmp %>%
nest(-GLB, -NDG) %>%
mutate(data = map2(data, NDG, sample_n)) %>%
unnest
一个优点是它不需要像 sample_frac
那样对所有数据行进行排列,这对于大型数据帧来说可能非常昂贵。