关注公众号,发送R语言或python获取资料
重点关注R语言在生物医学中的运用
随机分组在临床设计中太常见了。 临床上常用的随机分组方法有四种:
当然,还有其他类型。 关于随机分组的问题,推荐大家看一下医学咖啡俱乐部的这篇文章:10篇文章,全面理解随机分组。 赶快收藏起来吧! [1]
本文主要介绍如何使用R语言完成随机分组。
简单随机化,也称为完全随机化,是最简单的随机分组方法。 在医学统计中,我们经常会遇到完全随机设计的xxx,指的是简单随机分组!
比如,病人来了,抛硬币,根据正面和反面随机决定进入实验组还是对照组。 然而,实际操作却没有那么随意。 每个人都只是通过随机数字表方法或软件随机分组。 原理几乎是一样的。
如果需要收集100名受试者,随机分为实验组和对照组,可以按照每位患者入院的顺序给其编号,然后从随机编号表的任意行或列开始并抽取一个随机数, 100 每个科目有 100 个随机数。 将这 100 个随机数从小到大排序。 前50名进入实验组,后50名进入对照组(余数、单双数等也可以)。
上述方法可以通过SPSS来实现。 可以参考这篇文章:SPSS实现简单随机分组[2]
按照这个思路,R语言也可以实现。 R语言在临床研究设计中的使用已经非常成熟。 Cran 任务视图中有两个关于研究设计的主题。 如果您有兴趣,可以自己看一下。
简单随机
例如,将30人按照完全随机的方法分为2组,实验组和对照组,每组15人。
id <- c(1:30)
group <- rep(c("试验组","对照组"),15)
rand <- sample(group, 30, replace = T)
(res <- cbind(id, group))
## id group
## [1,] "1" "试验组"
## [2,] "2" "对照组"
## [3,] "3" "试验组"
## [4,] "4" "对照组"
## [5,] "5" "试验组"
## [6,] "6" "对照组"
## [7,] "7" "试验组"
## [8,] "8" "对照组"
## [9,] "9" "试验组"
## [10,] "10" "对照组"
## [11,] "11" "试验组"
## [12,] "12" "对照组"
## [13,] "13" "试验组"
## [14,] "14" "对照组"
## [15,] "15" "试验组"
## [16,] "16" "对照组"
## [17,] "17" "试验组"
## [18,] "18" "对照组"
## [19,] "19" "试验组"
## [20,] "20" "对照组"
## [21,] "21" "试验组"
## [22,] "22" "对照组"
## [23,] "23" "试验组"
## [24,] "24" "对照组"
## [25,] "25" "试验组"
## [26,] "26" "对照组"
## [27,] "27" "试验组"
## [28,] "28" "对照组"
## [29,] "29" "试验组"
## [30,] "30" "对照组"
我们还可以通过 randomizr 包来实现这一点。 如果没有安装,需要先安装。
install.packages("randomizr")
“抛硬币”风格的简单随机分组是通过 simple_ra() 函数实现的:
library(randomizr)
# 100人分2组
sim <- simple_ra(100, num_arms = 2, conditions = c("试验组","对照组"))
sim
## [1] 试验组 对照组 对照组 对照组 对照组 试验组 试验组 对照组 对照组 对照组
## [11] 对照组 试验组 对照组 对照组 试验组 试验组 对照组 对照组 对照组 试验组
## [21] 试验组 试验组 试验组 对照组 试验组 对照组 试验组 对照组 试验组 试验组
## [31] 试验组 对照组 对照组 试验组 对照组 试验组 对照组 试验组 试验组 试验组
## [41] 试验组 试验组 对照组 对照组 对照组 试验组 试验组 试验组 试验组 对照组
## [51] 对照组 试验组 对照组 对照组 对照组 对照组 试验组 对照组 试验组 试验组
## [61] 试验组 对照组 对照组 试验组 试验组 试验组 对照组 试验组 对照组 试验组
## [71] 对照组 试验组 试验组 对照组 试验组 对照组 对照组 对照组 对照组 试验组
## [81] 对照组 对照组 试验组 试验组 试验组 对照组 试验组 试验组 试验组 对照组
## [91] 试验组 试验组 对照组 试验组 试验组 试验组 试验组 试验组 对照组 对照组
## Levels: 试验组 对照组
table(sim)
## sim
## 试验组 对照组
## 53 47
但这种分组最大的问题是分组人数不同,在临床研究设计中通常是1:1。 我们可以使用另一个函数来解决这个问题。
com <- complete_ra(100, num_arms = 2, conditions = c("试验组","对照组"))
com
## [1] 对照组 试验组 对照组 试验组 试验组 对照组 试验组 对照组 试验组 对照组
## [11] 试验组 对照组 对照组 对照组 试验组 对照组 对照组 试验组 对照组 试验组
## [21] 对照组 试验组 对照组 对照组 试验组 试验组 对照组 对照组 试验组 对照组
## [31] 对照组 试验组 对照组 对照组 对照组 对照组 对照组 试验组 试验组 对照组
## [41] 试验组 试验组 对照组 对照组 试验组 试验组 对照组 对照组 试验组 对照组
## [51] 对照组 试验组 试验组 试验组 试验组 试验组 试验组 试验组 试验组 对照组
## [61] 对照组 对照组 试验组 试验组 对照组 试验组 对照组 对照组 试验组 对照组
## [71] 对照组 试验组 试验组 对照组 对照组 试验组 试验组 试验组 对照组 试验组
## [81] 试验组 对照组 对照组 对照组 试验组 试验组 对照组 试验组 试验组 试验组
## [91] 试验组 试验组 对照组 试验组 对照组 对照组 试验组 对照组 试验组 对照组
## Levels: 试验组 对照组
table(com)
## com
## 试验组 对照组
## 50 50
完美解决群体间人数不对等的问题。
网上的高手也给出了自己写的函数:
simple_random <- function(size, grp = 2, T_2_C = "1:1"){
set.seed(20210412)
id_num <- seq(1, size, 1)
random_seq <- runif(n = size, min = 0, max = 1)
int_rank <- rank(random_seq)
ratio_T <- as.numeric(substr(T_2_C, 1, 1))
ratio_C <- as.numeric(substr(T_2_C, 3, 3))
if (grp == 2) {
group <- ifelse(int_rank <= size/(ratio_T + ratio_C), "T", "C")
} else if (grp > 3) {
group <- cut(int_rank, breaks = grp, labels = paste("Group", 1:grp))
}
df <- data.frame("ID" = id_num, "RandomNum" = random_seq,
"Rank" = int_rank, "Group" = group)
#write.csv(df, "simple randomization table.csv", row.names = FALSE)
return(df)
}
20人随机分为几组:
simple_random(20)
## ID RandomNum Rank Group
## 1 1 0.83237492 19 C
## 2 2 0.95522177 20 C
## 3 3 0.59787880 10 T
## 4 4 0.35076793 4 T
## 5 5 0.43157421 6 T
## 6 6 0.63326323 13 C
## 7 7 0.78015581 17 C
## 8 8 0.46990952 7 T
## 9 9 0.38535395 5 T
## 10 10 0.63361183 14 C
## 11 11 0.73655082 15 C
## 12 12 0.49675139 8 T
## 13 13 0.61201021 11 C
## 14 14 0.23511285 3 T
## 15 15 0.52894214 9 T
## 16 16 0.04290597 1 T
## 17 17 0.74367251 16 C
## 18 18 0.79647582 18 C
## 19 19 0.62653890 12 C
## 20 20 0.22537775 2 T
另外,有很多R包可以实现随机分组,包括但不限于简单随机分组/分块随机化/分层随机化等。
块随机
您可以使用 randomizr 来实现块随机化:
# Load built-in dataset
data(HairEyeColor)
HairEyeColor <- data.frame(HairEyeColor)
# Transform so each row is a subject
# Columns describe subjects hair color, eye color, and gender
hec <- HairEyeColor[rep(1:nrow(HairEyeColor),
times = HairEyeColor$Freq), 1:3]
N <- nrow(hec)
# Fix the rownames
rownames(hec) <- NULL
dim(hec)
## [1] 592 3
head(hec)
## Hair Eye Sex
## 1 Black Brown Male
## 2 Black Brown Male
## 3 Black Brown Male
## 4 Black Brown Male
## 5 Black Brown Male
## 6 Black Brown Male
根据头发颜色进入不同的组,然后分为3组:
Z <- block_ra(blocks = hec$Hair, conditions = c("Control", "Placebo", "Treatment"))
table(Z, hec$Hair)
##
## Z Black Brown Red Blond
## Control 36 95 24 42
## Placebo 36 96 23 42
## Treatment 36 95 24 43
您可以自由控制组数:
sort(unique(hec$Hair))
## [1] Black Brown Red Blond
## Levels: Black Brown Red Blond
block_m_each <- rbind(c(78, 30),
c(186, 100),
c(51, 20),
c(87,40))
block_m_each
## [,1] [,2]
## [1,] 78 30
## [2,] 186 100
## [3,] 51 20
## [4,] 87 40
Z <- block_ra(blocks = hec$Hair, block_m_each = block_m_each)
table(Z, hec$Hair)
##
## Z Black Brown Red Blond
## 0 78 186 51 87
## 1 30 100 20 40
然而,这种分组随机化不太适合临床研究,因为这里的情况需要所有受试者提前做好准备,然后进行分组。 对于临床研究来说,受试者是一一来的,并不是一下子全部都有的,所以block_ra()可能更适合动物实验或者基础研究分组。 关于分块随机化的更多知识,可以参考医学咖啡协会的这篇文章:一篇文章详细讲解分块随机化,包括教育和理解! [3]
通过blockrand包可以实现临床研究的随机分组,特别适合一次招募一个人的临床研究!
例如,100人随机分为2组,每组50人:
library(blockrand)
set.seed(111)
res <- blockrand(n=100, num.levels = 2, levels = c("试验组","对照组"))
head(res)
## id block.id block.size treatment
## 1 1 1 4 试验组
## 2 2 1 4 对照组
## 3 3 1 4 试验组
## 4 4 1 4 对照组
## 5 5 2 6 试验组
## 6 6 2 6 试验组
# 结果并不是50 50,因为block size不一样
table(res$treatment)
##
## 对照组 试验组
## 51 51
您还可以帮助我们生成 PDF 文。