如何在R中按品种分组随机化试验处理编号?
谷物试验区组随机化的R实现方法
需求说明
现有如下试验数据:
Grain <- tibble::tibble( Variety = rep(c("CV1", "CV2"), each = 4L), `N rate` = rep(c("0N", "50N", "100N", "150N"), 2), `Rep 1` = seq(101, 108, by = 1), `Rep 2` = seq(201, 208, by = 1), `Rep 3` = seq(301, 308, by = 1), `Rep 4` = seq(401, 408, by = 1), )
原数据中,CV1对应各Rep列的前4个编号区间(如Rep1的101-104),CV2对应后4个区间(如Rep1的105-108)。原随机化代码仅能组内打乱顺序,但区间分配固定:
library(dplyr) set.seed(123) Grain_randomized <- Grain %>% group_by(Variety) %>% mutate(across(starts_with("Rep"), ~ sample(.x))) %>% ungroup()
需要实现的效果是:每个Rep列的编号区间在两个品种间随机分配,同时每个品种内的Rep编号保持连续,且组内顺序可打乱。
实现代码
library(dplyr) set.seed(123) # 固定随机种子保证结果可重复 # 定义每个Rep列的区间拆分与随机分配逻辑 split_rep <- function(rep_col) { # 拆分出前后各4个编号的区间 group1 <- head(rep_col, 4) group2 <- tail(rep_col, 4) # 随机决定哪个区间分配给CV1,同时打乱区间内的编号顺序 if (sample(c(TRUE, FALSE), 1)) { c(sample(group1), sample(group2)) } else { c(sample(group2), sample(group1)) } } # 对所有Rep列批量应用随机化逻辑 Grain_final <- Grain %>% mutate(across(starts_with("Rep"), split_rep))
代码解释
split_rep函数:针对单个Rep列,先拆分出前后各4个编号的区间,通过sample(c(TRUE, FALSE),1)随机决定区间分配给CV1的方向,同时对每个区间内的编号进行随机打乱,既保证品种内编号连续,又实现组内顺序随机。across(starts_with("Rep"), split_rep):批量对所有Rep列应用上述逻辑,无需单独处理每一列。
运行后即可得到符合要求的随机化结果,示例输出如下:
# A tibble: 8 × 6 Variety `N rate` `Rep 1` `Rep 2` `Rep 3` `Rep 4` <chr> <chr> <int> <int> <int> <int> 1 CV1 0N 103 206 304 407 2 CV1 50N 104 205 301 408 3 CV1 100N 101 207 303 406 4 CV1 150N 102 208 302 405 5 CV2 0N 107 201 305 402 6 CV2 50N 106 204 308 401 7 CV2 100N 108 202 307 403 8 CV2 150N 105 203 306 404
内容的提问来源于stack exchange,提问作者J.K Kim
相关产品推荐
相关产品推荐

