Skip to contents

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. For method = "onestage" it is passed to blocksdesign::design() as its number of searches (default 200; values beyond a few hundred rarely improve the design). For method = "twostage" it is the number of greedy row-swap iterations (default 1000). If NULL (the default), a value appropriate to the chosen method is 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 with blocksdesign::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 the Row-by-Column row of blocksModel); for "onestage" the iterations argument is passed as the number of searches to blocksdesign::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 default FALSE. Only meaningful with method = "onestage"; it is ignored for method = "twostage" (which cannot latinize across replicates), where passing latinize = TRUE is ignored with a warning.

Value

A list with five elements.

  • infoDesign is a list with information on the design parameters.

  • blocksModel is a list (one element per location) with the efficiency of the design. In addition to the per-factor Rep, Row and Column A- and D-Efficiencies, it reports a Row-by-Column row with the joint A- and D-Efficiency of the standard resolvable row-column analysis model (rows and columns adjusted together).

  • resolvableBlocks a list with the resolvable row columns blocks.

  • concurrence is the concurrence matrix.

  • fieldBook is 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