Skip to content

Commit

Permalink
Merge pull request #49 from DidierMurilloF/fix-random-square-lattice
Browse files Browse the repository at this point in the history
Fix random square lattice
  • Loading branch information
DidierMurilloF authored Jul 2, 2024
2 parents 71f1e23 + 3066aa5 commit be1e801
Show file tree
Hide file tree
Showing 22 changed files with 458 additions and 162 deletions.
5 changes: 4 additions & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ $run_dev.*
^vignettes/methods\.Rmd$
^vignettes/latin_square\.Rmd$
^vignettes/strip_plot\.Rmd$
^vignettes/split_split_plot\.Rmd$
^vignettes/split_split_plot\.Rmd$
^vignettes/incomplete_blocks\.Rmd$
^vignettes/rectangular_lattice\.Rmd$
^vignettes/square_lattice\.Rmd$
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: FielDHub
Title: A Shiny App for Design of Experiments in Life Sciences
Version: 1.3.8
Version: 1.4.0
Authors@R:
c(person(given = "Didier",
family = "Murillo",
Expand Down Expand Up @@ -59,7 +59,7 @@ Imports:
desplot,
shinyjs
Encoding: UTF-8
RoxygenNote: 7.2.3
RoxygenNote: 7.3.1
Author: Didier Murillo [cre, aut], Salvador Gezan [aut], Ana Heilman [ctb],
Thomas Walk [ctb], Johan Aparicio [ctb], Matthew Seefeldt [ctb],
Jean-Marc Montpetit [ctb], Richard Horsley [ctb],
Expand Down
3 changes: 2 additions & 1 deletion R/fct_alpha_lattice.R
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ alpha_lattice <- function(t = NULL,
matdf <- incomplete_blocks(t = nt, k = nunits, r = r, l = l, plotNumber = plotNumber,
seed = seed, locationNames = locationNames,
data = data_alpha)
blocksModel <- matdf$blocksModel
lambda <- r*(k - 1)/(nt - 1)
matdf <- matdf$fieldBook
OutAlpha <- as.data.frame(matdf)
Expand All @@ -146,7 +147,7 @@ alpha_lattice <- function(t = NULL,
infoDesign <- list(Reps = r, iBlocks = s, NumberTreatments = nt, NumberLocations = l,
Locations = locationNames, seed = seed, lambda = lambda,
id_design = 12)
output <- list(infoDesign = infoDesign, fieldBook = OutAlpha)
output <- list(infoDesign = infoDesign, fieldBook = OutAlpha, blocksModel = blocksModel)
class(output) <- "FielDHub"
return(invisible(output))
}
54 changes: 11 additions & 43 deletions R/fct_incomplete_blocks.R
Original file line number Diff line number Diff line change
Expand Up @@ -134,56 +134,24 @@ incomplete_blocks <- function(t = NULL, k = NULL, r = NULL, l = 1, plotNumber =
square <- FALSE
if (sqrt(nt) == round(sqrt(nt))) square <- TRUE
outIBD_loc <- vector(mode = "list", length = l)
blocks_model <- list()
for (i in 1:l) {
if (square) {
mydes <- blocksdesign::blocks(treatments = nt, replicates = r + 1, blocks = list(r + 1, b), seed = NULL)
##### Dropping the cyclical REP ######
# Function to check if treatments are consecutive
check_consecutive <- function(treatments) {
sorted_treatments <- sort(treatments)
all(diff(sorted_treatments) == 1)
}
# Apply check_consecutive function to each Level_2 group
raw_design <- as.data.frame(mydes$Design)
raw_design <- raw_design |>
dplyr::mutate(
Level_1 = as.character(Level_1),
Level_2 = as.character(Level_2),
plots = as.integer(plots),
treatments = as.integer(treatments)
)
results <- raw_design |>
dplyr::group_by(Level_1, Level_2) |>
dplyr::summarise(are_consecutive = check_consecutive(treatments), .groups = "drop") |>
dplyr::group_by(Level_1) |>
dplyr::summarise(all_consecutive = all(are_consecutive))

# Filter Level_1 where all Level_2 levels have consecutive treatments
consecutive_levels <- results |>
dplyr::filter(all_consecutive) |>
dplyr::pull(Level_1) |>
unique()

consecutive_levels_level_1 <- consecutive_levels

if (length(consecutive_levels_level_1) > 0) {
rep_to_drop <- consecutive_levels_level_1[1]
mydes$Design <- dplyr::filter(raw_design, Level_1 != rep_to_drop)
} else {
mydes$Design <- raw_design |>
dplyr::filter(Level_1 != paste0("B", r + 1))
}
} else {
mydes <- blocksdesign::blocks(treatments = nt, replicates = r, blocks = list(r, b), seed = NULL)
}
mydes <- blocksdesign::blocks(treatments = nt, replicates = r, blocks = list(r, b), seed = NULL)
# print("---Blocks Model original design:---")
# print(mydes$Blocks_model)
mydes <- rerandomize_ibd(ibd_design = mydes)
# print("---Blocks Model re-randomized design:---")
# print(mydes$Blocks_model_new)
matdf <- base::data.frame(list(LOCATION = rep(locationNames[i], each = N)))
matdf$PLOT <- as.numeric(unlist(ibd_plots[[i]]))
matdf$BLOCK <- rep(c(1:r), each = nt)
matdf$iBLOCK <- rep(c(1:b), each = k)
matdf$UNIT <- rep(c(1:k), nincblock)
matdf$TREATMENT <- mydes$Design[,4]
# matdf$TREATMENT <- mydes$Design[,4]
matdf$TREATMENT <- mydes$Design_new[,4]
colnames(matdf) <- c("LOCATION","PLOT", "REP", "IBLOCK", "UNIT", "ENTRY")
outIBD_loc[[i]] <- matdf
blocks_model[[i]] <- mydes$Blocks_model_new
}
OutIBD <- dplyr::bind_rows(outIBD_loc)
OutIBD <- as.data.frame(OutIBD)
Expand All @@ -205,7 +173,7 @@ incomplete_blocks <- function(t = NULL, k = NULL, r = NULL, l = 1, plotNumber =
infoDesign <- list(Reps = r, iBlocks = b, NumberTreatments = nt, NumberLocations = l,
Locations = locationNames, seed = seed, lambda = lambda,
id_design = 8)
output <- list(infoDesign = infoDesign, fieldBook = OutIBD_new)
output <- list(infoDesign = infoDesign, fieldBook = OutIBD_new, blocksModel = blocks_model[[1]])
class(output) <- "FielDHub"
return(invisible(output))
}
Expand Down
3 changes: 2 additions & 1 deletion R/fct_rectangular_lattice.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ rectangular_lattice <- function(t = NULL, k = NULL, r = NULL, l = 1, plotNumber
matdf <- incomplete_blocks(t = nt, k = nunits, r = r, l = l, plotNumber = plotNumber,
seed = seed, locationNames = locationNames,
data = data_alpha)
blocksModel <- matdf$blocksModel
lambda <- r*(k - 1)/(nt - 1)
matdf <- matdf$fieldBook
OutRectagular_Lattice <- as.data.frame(matdf)
Expand All @@ -127,7 +128,7 @@ rectangular_lattice <- function(t = NULL, k = NULL, r = NULL, l = 1, plotNumber
infoDesign <- list(Reps = r, iBlocks = s, NumberTreatments = nt, NumberLocations = l,
Locations = locationNames, seed = seed, lambda = lambda,
id_design = 11)
output <- list(infoDesign = infoDesign, fieldBook = OutRectagular_Lattice)
output <- list(infoDesign = infoDesign, fieldBook = OutRectagular_Lattice, blocksModel = blocksModel)
class(output) <- "FielDHub"
return(invisible(output))
}
7 changes: 6 additions & 1 deletion R/fct_square_lattice.R
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ square_lattice <- function(t = NULL, k = NULL, r = NULL, l = 1, plotNumber = 101
matdf <- incomplete_blocks(t = nt, k = nunits, r = r, l = l, plotNumber = plotNumber,
seed = seed, locationNames = locationNames,
data = data_square)
blocksModel <- matdf$blocksModel
matdf <- matdf$fieldBook
OutSquare_Lattice <- as.data.frame(matdf)
OutSquare_Lattice$LOCATION <- factor(OutSquare_Lattice$LOCATION, levels = locationNames)
Expand All @@ -123,7 +124,11 @@ square_lattice <- function(t = NULL, k = NULL, r = NULL, l = 1, plotNumber = 101
infoDesign <- list(Reps = r, IBlocks = s, NumberTreatments = nt, NumberLocations = l,
Locations = locationNames, seed = seed, lambda = lambda,
id_design = 10)
output <- list(infoDesign = infoDesign, fieldBook = OutSquare_Lattice)
output <- list(
infoDesign = infoDesign,
fieldBook = OutSquare_Lattice,
blocksModel = blocksModel
)
class(output) <- "FielDHub"
return(invisible(output))
}
2 changes: 1 addition & 1 deletion R/globals.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ utils::globalVariables(c("ENTRY",
"Times",
"all_consecutive",
"are_consecutive",
"plots"))
"plots", "arcbd_plot", "new_order_treatments"))
86 changes: 86 additions & 0 deletions R/ibd_reorder_treatments.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#' Function to estimate the efficiencies of a IBD design
#' This function is sourced from the `blocksdesign` package.
#' @param TF Treatment factor levels
#' @param BF Block factor levels
#' @author Rodney Edmondson <rodney.edmondson at gmail.com>
#' @return List containing design and A efficiencies
#' @noRd
blockEstEffics = function(TF, BF) {
TM = qr.Q(qr(scale(stats::model.matrix(~TF))[, -1]))
BM = qr.Q(qr(scale(stats::model.matrix(~BF))[, -1]))
if (nlevels(TF) <= nlevels(BF))
E = eigen(diag(ncol(TM)) - tcrossprod(crossprod(TM,
BM)), symmetric = TRUE, only.values = TRUE)
else E = eigen(diag(ncol(BM)) - tcrossprod(crossprod(BM,
TM)), symmetric = TRUE, only.values = TRUE)
Deff = exp(sum(log(E$values))/ncol(TM))
if (nlevels(TF) <= nlevels(BF))
Aeff = ncol(TM)/sum(1/E$values)
else Aeff = ncol(TM)/(ncol(TM) - ncol(BM) + sum(1/E$values))
return(list(Deffic = round(Deff, 7), Aeffic = round(Aeff,
7)))
}

#' Function to estimate the A bound and report the efficiencies of a IBD design
#' This function is sourced from the `blocksdesign` package.
#' @param Design The IBD design matrix
#' @return Data frame of efficiencies and bounds
#' @author Rodney Edmondson <rodney.edmondson at gmail.com>
#' @noRd
BlockEfficiencies = function(Design) {
TF = Design[, ncol(Design)]
regreps = table(TF)
regReps = isTRUE(max(regreps) == min(regreps))
sizes = lapply(1:(ncol(Design) - 2), function(i) {
table(Design[, i])
})
regBlocks = sapply(1:length(sizes), function(i) {
max(sizes[[i]]) == min(sizes[[i]])
})
bounds = sapply(1:(ncol(Design) - 2), function(i) {
if (regBlocks[i] & regReps)
blocksdesign::A_bound(length(TF), nlevels(TF), nlevels(Design[,
i]))
else 1
})
blocklevs = unlist(lapply(1:(ncol(Design) - 2), function(j) {
nlevels(Design[, j])
}))
Effics = t(sapply(1:(ncol(Design) - 2), function(i) {
if (nlevels(Design[, i]) > 1)
blockEstEffics(TF, Design[, i])
else list(Deffic = 1, Aeffic = 1)
}))
efficiencies = data.frame(1:(ncol(Design) - 2), blocklevs,
as.numeric(Effics[, 1]), as.numeric(Effics[, 2]),
round(bounds, 7))
colnames(efficiencies) = c("Level", "Blocks", "D-Efficiency",
"A-Efficiency", "A-Bound")
return(efficiencies)
}

#' Function to re-randomize IBD design
#'
#' @param ibd_design Input design from the `blocksdesign` package
#' @return Modified IBD design with re-randomized treatments
#' @author Didier Murillo
#' @noRd
rerandomize_ibd <- function(ibd_design) {
mydes <- ibd_design
tretments <- sort(unique(mydes$Design$treatments))
new_order <- data.frame(
treatments = tretments,
new_order_treatments = sample(tretments, replace = FALSE)
)

newDesign <- mydes$Design |>
dplyr::left_join(new_order, by = "treatments")

mydes$Design_new <- newDesign |>
dplyr::select(-treatments) |>
dplyr::rename(treatments = new_order_treatments)

mydes$Blocks_model_new <- BlockEfficiencies(mydes$Design_new)

return(mydes)
}
16 changes: 16 additions & 0 deletions R/mod_Alpha_Lattice.R
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ mod_Alpha_Lattice_ui <- function(id) {
width = 8,
fluidRow(
tabsetPanel(
tabPanel(
"Summary design",
br(),
shinycssloaders::withSpinner(
verbatimTextOutput(outputId = ns("summary_alpha_lattice"),
placeholder = FALSE),
type = 4
),
style = "padding-right: 40px;"
),
tabPanel("Field Layout",

# hidden .csv download button
Expand Down Expand Up @@ -295,6 +305,12 @@ mod_Alpha_Lattice_server <- function(id){
)
})

output$summary_alpha_lattice <- renderPrint({
req(ALPHA_reactive())
cat("Randomization was successful!", "\n", "\n")
print(ALPHA_reactive(), n = 6)
})

upDateSites <- reactive({
req(alpha_inputs())
locs <- alpha_inputs()$sites
Expand Down
17 changes: 16 additions & 1 deletion R/mod_IBD.R
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ mod_IBD_ui <- function(id) {
width = 8,
fluidRow(
tabsetPanel(
tabPanel(
"Summary design",
br(),
shinycssloaders::withSpinner(
verbatimTextOutput(outputId = ns("summary_ibd"),
placeholder = FALSE),
type = 4
),
style = "padding-right: 40px;"
),
tabPanel("Field Layout",
shinyjs::useShinyjs(),
shinyjs::hidden(
Expand Down Expand Up @@ -309,7 +319,6 @@ mod_IBD_server <- function(id) {
}) |>
bindEvent(input$RUN.ibd)


IBD_reactive <- reactive({
req(get_data_ibd())

Expand Down Expand Up @@ -339,6 +348,12 @@ mod_IBD_server <- function(id) {
}) |>
bindEvent(input$RUN.ibd)

output$summary_ibd <- renderPrint({
req(IBD_reactive())
cat("Randomization was successful!", "\n", "\n")
print(IBD_reactive(), n = 6)
})

upDateSites <- eventReactive(input$RUN.ibd, {
req(input$l.ibd)
locs <- as.numeric(input$l.ibd)
Expand Down
Loading

0 comments on commit be1e801

Please sign in to comment.