R语言 在已分配治疗的组中进行平等的组随机化

lndjwyie  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(56)

我有一个80名受试者的列表,他们已经被随机分为4组(1-4)。现在,我想引入一个交叉设计,这样每个受试者最终都会被分到所有4组中。我试图用样本函数来做到这一点,但我需要剩下的3个随机分组的每个可能性的平均分布。
举例来说:受试者A已被随机分配至第1组。现在我需要随机分配其余3组(2、3、4),其余3组的随机分配有6个选项:234 243 324 342 423 432
因此,我需要确保最初分配到第1组(20名受试者)的每个受试者都得到上述6种排列之一的均匀分布。最初分配到第2、3和4组的每个受试者也是如此
我试

#for loop going through each row of the dataframe
for(x in 1:nrow(crossover)) {
  #TRIAL 2
  #randomly selects an integer between 1 and 4

 y<- sample(1:4, 1, replace = TRUE)
  
  #if it equals Assigned.Arm.Index, then randomly select again
 while (y == crossover$Assigned.Arm.Index[x]){

    y <- sample(1:4, 1, replace = FALSE)
  }
  
  #set New.Arm.Index column to y
  crossover$Trial_2[x] <- y

字符串
crossover是我的随机数的名字,assigned.arm.index是预先做好的初始随机数。我为剩下的随机数创建了3个新列,我试图填充。
当我就所有受试者的平等随机化问题寻求帮助时,我被告知使用rep函数,类似于:

sample(rep(1:6, 4) , rep= FALSE)


但这对我来说并不完全有意义。我是R的新手,感谢任何帮助!

yhived7q

yhived7q1#

如果我正确地解释了你的问题,基本上你想要的是一系列随机的拉丁方块,足以让每个主题都有一排4个不同的治疗方法。magic包中的rlatin()函数非常适合你想要的。
由于您已经将受试者随机分配到4个组中,因此我们将使用该列作为基础来连接每个受试者的剩余治疗值。在下面的示例中,“treatment1”是包含您已经随机分配的组值的列。
工作流程如下:
1.在df中创建一个“ranjoin”列,并根据您的“treatment1”组添加一个1到20之间的唯一随机值。换句话说,每组中的每个受试者都被分配了一个随机值。“ranjoin”将与“treatment1”一起使用,以连接剩余的治疗组,
1.创建一个80 x 4的随机4 x 4拉丁方块的矩形(df1),第一列对应于df中的“treatment1”
1.如同对df所做的那样,为df1“treatment1”组分配一个随机“ranjoin”值
1.使用DF和DF 1中的“treatment1”和“ranjoin”列完成每例受试者的抽样治疗组
让我们以第1组为例。在df中有20个受试者的“treatment1”值为1,随机唯一“ranjoin”值为1:20。在df 1中也有20个“treatment1”值为1,随机唯一“ranjoin”值为1:20.如果“受试者”1的“治疗1”值为1,“随机连接”值为7,来自df1的相应行被连接到主题“1”的行。这种方法的关键是“ranjoin”列是独立随机的。为了可重复性,我在整个示例中保持set.seed(1)相同。在下面的代码块,以确保更多的随机结果。

library(magic)
library(dplyr)
library(tidyr)

# Example of your existing df where "treatment1" contains your existing group sampling
# and subvar columns are just 'dummy' subject data
set.seed(1)
df <- data.frame(subject = 1:80,
                 treatment1 = rep(sample(1:4, 4, replace = FALSE), 20),
                 subvar1 = round(rnorm(80, 0, 10), 2),
                 subvar2 = round(rnorm(80, 0, 10), 2),
                 subvar3 = round(rnorm(80, 0, 10), 2)) 

# Assign random value between 1:n() so each treatment group has a random 'rank'
# set.seed(sample(1e+08:1e+09, 1)) # Use something like this before running

df <- df %>% 
  group_by(treatment1) %>%
  mutate(ranjoin = sample(1:n(), n(), replace = FALSE)) %>%
  ungroup()

head(data.frame(df))
  subject treatment1 subvar1 subvar2 subvar3 ranjoin
1       1          1   12.72   -2.20   16.80      20
2       2          3    4.15   -4.25    7.80       8
3       3          4  -15.40   -4.19    7.13       5
4       4          2   -9.29    9.97   -5.43      15
5       5          1   -2.95   -2.76    8.86       9
6       6          3   -0.06   12.56   -3.49       2

# Create 4 x 80 random treatments and join to df 
# set.seed(sample(1e+08:1e+09, 1)) # Use something like this again before running

df1 <- data.frame(rlatin(20, 4)) %>% # Create dataframe of 20 random 4 x 4 Latin squares
  mutate(names = paste0("treatment", 1:4)) %>%
  pivot_longer(-names) %>%
  pivot_wider(names_from = names,
              values_from = value) %>%
  group_by(treatment1) %>%
  mutate(ranjoin = sample(1:n(), n(), replace = FALSE)) %>% # Same as for df
  ungroup() %>%
  left_join(df, by = c("treatment1", "ranjoin"), keep = FALSE) %>%
  select(-c(name, ranjoin)) %>%
  relocate(subject) %>%
  arrange(subject)
  
head(data.frame(df1))
  subject treatment1 treatment2 treatment3 treatment4 subvar1 subvar2 subvar3
1       1          1          4          2          3   12.72   -2.20   16.80
2       2          3          4          1          2    4.15   -4.25    7.80
3       3          4          1          2          3  -15.40   -4.19    7.13
4       4          2          3          4          1   -9.29    9.97   -5.43
5       5          1          3          4          2   -2.95   -2.76    8.86
6       6          3          4          1          2   -0.06   12.56   -3.49

# Check treatment group sizes are equal per "treatment" column
table(stack(df1[,2:5]))
      ind
values treatment1 treatment2 treatment3 treatment4
     1         20         20         20         20
     2         20         20         20         20
     3         20         20         20         20
     4         20         20         20         20

# Check each subject has been assigned 4 different treatment values, 0 == TRUE
sum(apply(df1[,2:5], 1, function(x) length(unique(x))) < 4)
0

字符串

相关问题