rrandomized-algorithm

How to randomize variables per group using R?


In my experiment, I want to randomize treatments.

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),
)


Variety N rate  Rep 1   Rep 2   Rep 3   Rep 4
CV1     0N      101     201     301     401
CV1     50N     102     202     302     402
CV1     100N    103     203     303     403
CV1     150N    104     204     304     404
CV2     0N      105     205     305     405
CV2     50N     106     206     306     406
CV2     100N    107     207     307     407
CV2     150N    108     208     308     408

so, I used the following code:

library(dplyr)      
set.seed(123)       
Grain_randomized <- Grain %>%
  group_by(Variety) %>%
  mutate(across(starts_with("Rep"), ~ sample(.x))) %>%
  ungroup()
Grain_randomized

Variety N rate  Rep 1   Rep 2   Rep 3   Rep 4
CV1     0N      103     203     304     403
CV1     50N     104     201     301     402
CV1     100N    101     202     303     401
CV1     150N    102     204     302     404
CV2     0N      107     206     305     405
CV2     50N     106     205     308     406
CV2     100N    108     208     307     408
CV2     150N    105     207     306     407

It was randomized, but CV1 has always started as the first number, such as 101, 201, 301, 401. I want those variables to be randomized as well, but the numbers should be continuous within each variety, as shown below.

 Variety    N rate  Rep 1   Rep 2   Rep 3   Rep 4
    CV1     0N      103     206     304     407
    CV1     50N     104     205     301     408
    CV1     100N    101     207     303     406
    CV1     150N    102     208     302     405
    CV2     0N      107     201     305     402
    CV2     50N     106     204     308     401
    CV2     100N    108     202     307     403
    CV2     150N    105     203     306     404

Could you help me how to randomize variables like above table?

Thanks,


Solution

  • Extending Jay.sf's answer, we have:

    for (j in grep('^Rep\\s\\d$', names(Grain))) {
         Grain[[j]] <- ave(Grain[[j]][order(match(Grain$Variety,sample(unique(Grain$Variety))))], Grain$Variety, FUN=sample)
    }
    Grain
    
    # A tibble: 8 × 6
      Variety `N rate` `Rep 1` `Rep 2` `Rep 3` `Rep 4`
      <chr>   <chr>      <dbl>   <dbl>   <dbl>   <dbl>
    1 CV1     0N           103     203     306     406
    2 CV1     50N          101     201     305     407
    3 CV1     100N         104     204     308     405
    4 CV1     150N         102     202     307     408
    5 CV2     0N           107     206     303     401
    6 CV2     50N          106     205     301     403
    7 CV2     100N         105     207     302     402
    8 CV2     150N         108     208     304     404
    

    Equivalently in dplyr:

    Grain_randomized <- Grain %>%
      mutate(across(starts_with("Rep"), ~ ave(.x[order(match(Variety,sample(unique(Variety))))],Variety,FUN=sample)))
    
    # A tibble: 8 × 6
      Variety `N rate` `Rep 1` `Rep 2` `Rep 3` `Rep 4`
      <chr>   <chr>      <dbl>   <dbl>   <dbl>   <dbl>
    1 CV1     0N           102     204     306     401
    2 CV1     50N          103     201     307     402
    3 CV1     100N         101     203     308     403
    4 CV1     150N         104     202     305     404
    5 CV2     0N           108     206     302     407
    6 CV2     50N          106     205     304     406
    7 CV2     100N         107     208     301     405
    8 CV2     150N         105     207     303     408