How to randomise treatments in five blocks using Rstudio without a treatment being repeated?

149 Views Asked by At

In the orchard experiment, there are 5 treatments and 5 blocks. To allow for analysis of the effects of the treatments on tree and fruit growth the treatments are the same on either side of the middle tree row. How can I randomise the treatments in R without having the last treatment of a block being the same as the starting treatment of the next block. For example, I have used the agricolae package to randomise the treatments within their blocks but I get randomisation such as this:

Block 1: 3 1 5 2 4 
Block 2: 2 3 4 5 1
Block 3: 2 5 1 4 3 
Block 4: 1 5 3 4 2
Block 5: 2 3 1 5 4

As you can see block 4 finishes with treatment 2 and then block 5 starts with 2. I would like to avoid this if possible but I am not sure how to do it in r.

A visual representation of the experiment with the treatments not randomised within their plots:

The image is a visual representation of the experiment with the treatments not randomised within their plots

Running the solution below, I come across the issue of the new table not showing numbers.

Print screen of the command dput(head(data,20))

1

There are 1 best solutions below

4
On BEST ANSWER

Imagine you had data that looked like this:

head(data,10)
#     Block TreeMiddleRow
#1  Block 1   Treatment 1
#2  Block 1   Treatment 2
#3  Block 1   Treatment 3
#4  Block 1   Treatment 4
#5  Block 1   Treatment 5
#6  Block 2   Treatment 1
#7  Block 2   Treatment 2
#8  Block 2   Treatment 3
#9  Block 2   Treatment 4
#10 Block 2   Treatment 5

You could use a while loop to continue resampling by group until none of the block boundaries equaled each other:

treatments <- rep("Tretment",nrow(data))
while(any(treatments[head(cumsum(rle(data$Block)$lengths),-1)] == treatments[head(cumsum(rle(data$Block)$lengths),-1)+1])){
  treatments <<- unname(unlist(tapply(data$TreeMiddleRow,
                                      data$Block,
                                      FUN = function(x) sample(x,size = 5, replace = FALSE))))
}
data$TreeMiddleRow <- treatments
head(data,10)
#     Block TreeMiddleRow
#1  Block 1   Treatment 2
#2  Block 1   Treatment 3
#3  Block 1   Treatment 4
#4  Block 1   Treatment 5
#5  Block 1   Treatment 1
#6  Block 2   Treatment 2
#7  Block 2   Treatment 5
#8  Block 2   Treatment 3
#9  Block 2   Treatment 4
#10 Block 2   Treatment 1

Note that cumsum with rle allows us to return the indices of boundaries between blocks. head(x,-1) removes the last one because we don't care about it:

head(cumsum(rle(data$Block)$lengths),-1)
#[1]  5 10 15 20

Sample Data:

data <- data.frame(Block = rep(paste("Block",1:5),each = 5),
                   TreeMiddleRow = rep(paste("Treatment",1:5),times = 5))