It randomly generates a resolvable row-column design (RowColD). The design is optimized in both rows and columns blocking factors. The randomization can be done across multiple locations.
Usage
row_column(
t = NULL,
nrows = NULL,
r = NULL,
l = 1,
plotNumber = 101,
locationNames = NULL,
seed = NULL,
iterations = NULL,
data = NULL,
method = c("onestage", "twostage"),
latinize = FALSE
)Arguments
- t
Number of treatments.
- nrows
Number of rows of a full resolvable replicate.
- r
Number of blocks (full resolvable replicates).
- l
Number of locations. By default
l = 1.- plotNumber
Numeric vector with the starting plot number for each location. By default
plotNumber = 101.- locationNames
(optional) Names for each location.
- seed
(optional) Real number that specifies the starting seed to obtain reproducible designs.
- iterations
Number of optimization iterations. Its meaning and default depend on
method. Formethod = "onestage"it is passed toblocksdesign::design()as its number ofsearches(default 200; values beyond a few hundred rarely improve the design). Formethod = "twostage"it is the number of greedy row-swap iterations (default 1000). IfNULL(the default), a value appropriate to the chosenmethodis used.- data
(optional) Data frame with label list of treatments
- method
Optimization strategy for the row and column blocking factors. Either
"onestage"(default) or"twostage". With"onestage"(also known as simultaneous) the rows and columns are optimized jointly withblocksdesign::design(), which usually yields a higher joint row-by-column A-Efficiency while leaving the per-factor row and column efficiencies almost unchanged (see Details and theRow-by-Columnrow ofblocksModel); for"onestage"theiterationsargument is passed as the number ofsearchestoblocksdesign::design(). With"twostage"the columns are optimized first and the rows are then improved by a greedy search, keeping the columns fixed; this reproduces the designs generated by previous versions of FielDHub."onestage"automatically falls back to"twostage"(with a warning) for very small designs whose joint one-stage model is over-parameterized, so"twostage"rarely has to be requested explicitly.- latinize
If
TRUE, optimize the row and column blocking factors as crossed (latinized) effects shared across the replicates, so that each treatment tends to appear in different rows and columns across the replicates. By defaultFALSE. Only meaningful withmethod = "onestage"; it is ignored formethod = "twostage"(which cannot latinize across replicates), where passinglatinize = TRUEis ignored with a warning.
Value
A list with five elements.
infoDesignis a list with information on the design parameters.blocksModelis a list (one element per location) with the efficiency of the design. In addition to the per-factorRep,RowandColumnA- and D-Efficiencies, it reports aRow-by-Columnrow with the joint A- and D-Efficiency of the standard resolvable row-column analysis model (rows and columns adjusted together).resolvableBlocksa list with the resolvable row columns blocks.concurrenceis the concurrence matrix.fieldBookis a data frame with the row-column field book.
Details
With method = "twostage", the Row-Column design is built in two
stages. The first step
constructs the blocking factor Columns using Incomplete Block Units
from an incomplete block design that sets the number of incomplete blocks as
the number of Columns in the design, each of which has a dimension
equal to the number of Rows. Once this design is generated, the
Rows are used as the Row blocking factor that is optimized for
A-Efficiency, but levels within the original Columns are fixed.
To optimize the Rows while maintaining the current optimized Columns,
we use a heuristic algorithm that swaps at random treatment positions within
a given Column (Block) also selected at random. The algorithm begins
by calculating the A-Efficiency on the initial design, performs a swap iteration,
recalculates the A-Efficiency on the resulting design, and compares it with
the previous one to decide whether to keep or discard the new design. This
iterative process is repeated, by default, 1,000 times. This two-stage
greedy search reproduces the designs generated by previous versions of
FielDHub and is available via method = "twostage".
When method = "onestage" (the default, also called simultaneous),
the rows and columns are optimized jointly in a single stage with
blocksdesign::design() instead of optimizing the columns first and the
rows afterwards. The joint row-by-column A-Efficiency of the standard analysis
model (rows and columns adjusted together) is reported as the
Row-by-Column row of blocksModel. With the default
latinize = FALSE the joint optimization targets this within-replicate
criterion and typically increases it relative to "twostage"; with
latinize = TRUE it instead targets the across-replicate latinization
described below. The per-factor (marginal) Row and Column
A-Efficiencies are already close to optimal under both methods and differ only
slightly between them (and not systematically in one direction). The size of
the joint gain is layout-dependent and tends to be largest for small designs
with few replicates. For method = "onestage", the iterations
argument is passed to blocksdesign::design() as its number of
searches. For a very small design, the joint one-stage model can be
over-parameterized (no residual degrees of freedom); in that case
row_column() issues a warning and automatically falls back to
method = "twostage" rather than failing, so a design is still
produced.
Setting latinize = TRUE (only available with method =
"onestage") codes the rows and columns as crossed blocking factors shared
across the replicates, so that a treatment tends to occupy different rows and
different columns in the different replicates (a latinized resolvable
row-column design in the sense of John and Williams). This guards against the
same treatment recurring in the same field row or column over the whole trial,
not just within a replicate, and is useful when a field trend runs along the
whole-field rows or columns. It optimizes a different (crossed) model than the
default nested one, so the two are not directly comparable, and full
latinization is only possible when there are at least as many rows and columns
as replicates. By default (latinize = FALSE) the rows and columns stay
nested within each replicate. latinize has no effect for
method = "twostage", which cannot latinize across replicates.
References
Edmondson., R. N. (2021). blocksdesign: Nested and crossed block designs for factorial and unstructured treatment sets. https://CRAN.R-project.org/package=blocksdesign
Author
Didier Murillo [aut], Salvador Gezan [aut], Ana Heilman [ctb], Thomas Walk [ctb], Johan Aparicio [ctb], Richard Horsley [ctb]
Examples
# Example 1: Generates a row-column design with 2 full blocks and 24 treatments
# and 6 rows, for one location. This uses the default method = "onestage", for
# which a small number of iterations (passed as searches) already captures most
# of the joint-efficiency gain.
rowcold1 <- row_column(
t = 24,
nrows = 6,
r = 2,
l = 1,
plotNumber= 101,
locationNames = "Loc1",
iterations = 20,
seed = 21
)
rowcold1$infoDesign
#> $rows
#> [1] 6
#>
#> $columns
#> [1] 4
#>
#> $reps
#> [1] 2
#>
#> $treatments
#> [1] 24
#>
#> $locations
#> [1] 1
#>
#> $location_names
#> [1] "Loc1"
#>
#> $seed
#> [1] 21
#>
#> $optimization
#> [1] "onestage"
#>
#> $id_design
#> [1] 9
#>
rowcold1$resolvableBlocks
#> $Loc_Loc1
#> $Loc_Loc1$rep1
#> [,1] [,2] [,3] [,4]
#> [1,] NA NA NA NA
#> [2,] NA NA NA NA
#> [3,] NA NA NA NA
#> [4,] NA NA NA NA
#> [5,] NA NA NA NA
#> [6,] NA NA NA NA
#>
#> $Loc_Loc1$rep2
#> [,1] [,2] [,3] [,4]
#> [1,] NA NA NA NA
#> [2,] NA NA NA NA
#> [3,] NA NA NA NA
#> [4,] NA NA NA NA
#> [5,] NA NA NA NA
#> [6,] NA NA NA NA
#>
#>
head(rowcold1$fieldBook,12)
#> ID LOCATION PLOT REP ROW COLUMN ENTRY TREATMENT
#> 1 1 Loc1 101 1 1 1 21 G-21
#> 2 2 Loc1 102 1 1 2 8 G-8
#> 3 3 Loc1 103 1 1 3 4 G-4
#> 4 4 Loc1 104 1 1 4 7 G-7
#> 5 5 Loc1 105 1 2 1 12 G-12
#> 6 6 Loc1 106 1 2 2 6 G-6
#> 7 7 Loc1 107 1 2 3 23 G-23
#> 8 8 Loc1 108 1 2 4 24 G-24
#> 9 9 Loc1 109 1 3 1 22 G-22
#> 10 10 Loc1 110 1 3 2 9 G-9
#> 11 11 Loc1 111 1 3 3 1 G-1
#> 12 12 Loc1 112 1 3 4 17 G-17
# Example 2: Generates a row-column design with 2 full blocks and 30 treatments
# and 5 rows, for one location, using the default method = "onestage".
# In this case, we show how to use the option data.
treatments <- paste("ND-", 1:30, sep = "")
ENTRY <- 1:30
treatment_list <- data.frame(list(ENTRY = ENTRY, TREATMENT = treatments))
head(treatment_list)
#> ENTRY TREATMENT
#> 1 1 ND-1
#> 2 2 ND-2
#> 3 3 ND-3
#> 4 4 ND-4
#> 5 5 ND-5
#> 6 6 ND-6
rowcold2 <- row_column(
t = 30,
nrows = 5,
r = 2,
l = 1,
plotNumber= 1001,
locationNames = "A",
seed = 15,
iterations = 20,
data = treatment_list
)
rowcold2$infoDesign
#> $rows
#> [1] 5
#>
#> $columns
#> [1] 6
#>
#> $reps
#> [1] 2
#>
#> $treatments
#> [1] 30
#>
#> $locations
#> [1] 1
#>
#> $location_names
#> [1] "A"
#>
#> $seed
#> [1] 15
#>
#> $optimization
#> [1] "onestage"
#>
#> $id_design
#> [1] 9
#>
rowcold2$resolvableBlocks
#> $Loc_A
#> $Loc_A$rep1
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] NA NA NA NA NA NA
#> [2,] NA NA NA NA NA NA
#> [3,] NA NA NA NA NA NA
#> [4,] NA NA NA NA NA NA
#> [5,] NA NA NA NA NA NA
#>
#> $Loc_A$rep2
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] NA NA NA NA NA NA
#> [2,] NA NA NA NA NA NA
#> [3,] NA NA NA NA NA NA
#> [4,] NA NA NA NA NA NA
#> [5,] NA NA NA NA NA NA
#>
#>
head(rowcold2$fieldBook,12)
#> ID LOCATION PLOT REP ROW COLUMN ENTRY TREATMENT
#> 1 1 A 1001 1 1 1 21 ND-21
#> 2 2 A 1002 1 1 2 18 ND-18
#> 3 3 A 1003 1 1 3 23 ND-23
#> 4 4 A 1004 1 1 4 12 ND-12
#> 5 5 A 1005 1 1 5 1 ND-1
#> 6 6 A 1006 1 1 6 5 ND-5
#> 7 7 A 1007 1 2 1 2 ND-2
#> 8 8 A 1008 1 2 2 10 ND-10
#> 9 9 A 1009 1 2 3 29 ND-29
#> 10 10 A 1010 1 2 4 9 ND-9
#> 11 11 A 1011 1 2 5 7 ND-7
#> 12 12 A 1012 1 2 6 17 ND-17
# Example 3: Same design as Example 1 but using the historical two-stage
# optimization (method = "twostage"), which reproduces the designs generated
# by previous versions of FielDHub. For twostage, iterations is the number of
# greedy row-swap iterations; its default is 1000, but a smaller value is
# used here to keep the example quick.
rowcold3 <- row_column(
t = 24,
nrows = 6,
r = 2,
l = 1,
plotNumber = 101,
locationNames = "Loc1",
iterations = 100,
method = "twostage",
seed = 21
)
rowcold3$infoDesign
#> $rows
#> [1] 6
#>
#> $columns
#> [1] 4
#>
#> $reps
#> [1] 2
#>
#> $treatments
#> [1] 24
#>
#> $locations
#> [1] 1
#>
#> $location_names
#> [1] "Loc1"
#>
#> $seed
#> [1] 21
#>
#> $optimization
#> [1] "twostage"
#>
#> $id_design
#> [1] 9
#>
# The Row-by-Column row reports the joint row-by-column A-Efficiency.
rowcold3$blocksModel
#> [[1]]
#> Level Blocks D-Efficiency A-Efficiency A-Bound
#> 1 Rep 2 1.0000000 1.0000000 1.0000000
#> 2 Row 12 0.7225014 0.6500942 0.6592357
#> 3 Column 8 0.8304469 0.7804391 0.8070175
#> 4 Row-by-Column NA 0.5459002 0.3939678 NA
#>
head(rowcold3$fieldBook, 12)
#> ID LOCATION PLOT REP ROW COLUMN ENTRY TREATMENT
#> 1 1 Loc1 101 1 1 1 13 G-13
#> 7 2 Loc1 102 1 1 2 23 G-23
#> 13 3 Loc1 103 1 1 3 10 G-10
#> 19 4 Loc1 104 1 1 4 12 G-12
#> 2 5 Loc1 105 1 2 1 20 G-20
#> 8 6 Loc1 106 1 2 2 8 G-8
#> 14 7 Loc1 107 1 2 3 6 G-6
#> 20 8 Loc1 108 1 2 4 19 G-19
#> 3 9 Loc1 109 1 3 1 24 G-24
#> 9 10 Loc1 110 1 3 2 11 G-11
#> 15 11 Loc1 111 1 3 3 21 G-21
#> 21 12 Loc1 112 1 3 4 5 G-5