在R中无需循环按第一组水平重采样第二组成员并计算统计量
简洁实现分组内打乱并计算统计量的方法
你需要的是在每个grpOne(或物种)分组内打乱grpTwo(或性别)的归属,再计算分组间的统计量(比如均值差),无需手动遍历分组。利用dplyr的分组操作结合自定义逻辑就能实现,以下是具体方案:
核心思路
通过group_by(grpOne)将数据按目标分组拆分,再对每个子分组执行:
- 打乱当前组内的
grpTwo变量 - 计算打乱后的
grpTwo分组统计量差值
方案1:自定义函数+group_by()+summarise()
先定义通用的统计量计算函数,再对每个分组调用该函数:
针对初始数据集的实现
library(tidyverse) # 生成示例数据 df <- data.frame(x = rnorm(80), grpOne = rep(letters[1:4],10), grpTwo = rep(rep(LETTERS[25:26],each=4),10)) # 定义计算打乱后均值差的函数 compute_shuffled_mean_diff <- function(sub_data) { # 打乱当前分组内的grpTwo shuffled_grp <- sample(sub_data$grpTwo) # 计算打乱后的grpTwo分组均值差 sub_data %>% mutate(grpTwo_shuffled = shuffled_grp) %>% group_by(grpTwo_shuffled) %>% summarise(mean_x = mean(x), .groups = "drop") %>% pull(mean_x) %>% diff() } # 按grpOne分组计算结果 df %>% group_by(grpOne) %>% summarise(shuffled_mean_diff = compute_shuffled_mean_diff(cur_data()), .groups = "drop")
针对企鹅数据集的实现
library(tidyverse) library(palmerpenguins) # 预处理企鹅数据 penguins_df <- penguins %>% filter(!is.na(sex)) %>% select(species, body_mass_g, sex) # 定义企鹅体重均值差的计算函数 compute_penguin_shuffled_diff <- function(sub_data) { shuffled_sex <- sample(sub_data$sex) sub_data %>% mutate(sex_shuffled = shuffled_sex) %>% group_by(sex_shuffled) %>% summarise(mean_mass = mean(body_mass_g), .groups = "drop") %>% pull(mean_mass) %>% diff() } # 按物种分组计算打乱后的体重均值差 penguins_df %>% group_by(species) %>% summarise(shuffled_mass_diff = compute_penguin_shuffled_diff(cur_data()), .groups = "drop")
方案2:内联逻辑(无需单独定义函数)
如果不想单独写函数,可把逻辑直接嵌入summarise中,代码更紧凑:
# 企鹅数据集的内联实现示例 penguins_df %>% group_by(species) %>% summarise( shuffled_mass_diff = { # 内联打乱+计算逻辑 shuffled_sex <- sample(sex) data.frame(sex = shuffled_sex, mass = body_mass_g) %>% group_by(sex) %>% summarise(m = mean(mass), .groups = "drop") %>% pull(m) %>% diff() }, .groups = "drop" )
进阶:多次打乱(置换检验场景)
如果需要重复多次打乱以做置换检验,结合purrr::map即可实现每个分组生成多个统计量:
# 每个物种重复100次打乱,生成均值差列表 penguins_df %>% group_by(species) %>% summarise( shuffled_diffs = list(map_dbl(1:100, ~{ shuffled_sex <- sample(sex) data.frame(sex = shuffled_sex, mass = body_mass_g) %>% group_by(sex) %>% summarise(m = mean(mass), .groups = "drop") %>% pull(m) %>% diff() })), .groups = "drop" )
关键函数说明
group_by():自动拆分数据为指定分组的子数据集cur_data():获取当前分组的子数据集,确保函数只处理当前组内的数据sample():无放回抽样,实现变量归属的打乱pull() %>% diff():提取分组统计量后计算差值(注意diff()的结果顺序由分组水平决定,若需固定顺序可先对分组变量排序)
内容的提问来源于stack exchange,提问作者user111024
相关产品推荐
相关产品推荐

