From 3fb0ee7cad3a7b773375a3493209ee783fd62699 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:15:38 -0400 Subject: [PATCH 01/32] Fix missing `FUN.VALUE` in `vapply` call when resuming `ped2com` checkpoint (#139) * Initial plan * Fix vapply missing FUN.VALUE argument in .loadOrComputeParList Co-authored-by: smasongarrison <6001608+smasongarrison@users.noreply.github.com> Agent-Logs-Url: https://github.com/R-Computing-Lab/BGmisc/sessions/93bb6734-9e37-4cd1-b415-9d67049126ca --------- Co-Authored-By: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-Authored-By: smasongarrison <6001608+smasongarrison@users.noreply.github.com> --- .gitignore | 1 + R/buildComponent.R | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a69f0c70..4a53a3da 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ vignettes/rewritten_relatedness_vignette.Rmd vignettes/understanding_relatedness.Xmd vignettes/rewritten_relatedness_vignette.Xmd revdep/ +/.claude diff --git a/R/buildComponent.R b/R/buildComponent.R index bef313f5..bda8ad32 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -841,7 +841,7 @@ loadOrComputeCheckpoint <- function(file, compute_fn, } parList <- readRDS(checkpoint_files$parList) lens <- readRDS(checkpoint_files$lens) - computed_indices <- which(!vapply(parList, is.null)) + computed_indices <- which(!vapply(parList, is.null, logical(1))) lastComputed <- if (length(computed_indices) > 0) { max(computed_indices) } else { From ffe4b0e4a6a319b628c00394e5b6b877605b408f Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 12:36:28 -0400 Subject: [PATCH 02/32] split to move wrappers to own file --- R/buildComponent.R | 173 ------------------------------------- R/buildComponentWrappers.R | 173 +++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 173 deletions(-) create mode 100644 R/buildComponentWrappers.R diff --git a/R/buildComponent.R b/R/buildComponent.R index bda8ad32..50ae5791 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -431,179 +431,6 @@ ped2com <- function(ped, component, r } -#' Take a pedigree and turn it into an additive genetics relatedness matrix -#' @inheritParams ped2com -#' @inherit ped2com details -#' @export -#' -ped2add <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, - gc = FALSE, - flatten_diag = FALSE, standardize_colnames = TRUE, - transpose_method = "tcrossprod", - adjacency_method = "direct", - saveable = FALSE, - resume = FALSE, - save_rate = 5, - save_rate_gen = save_rate, - save_rate_parlist = 100000 * save_rate, - save_path = "checkpoint/", - compress = TRUE, - mz_twins = FALSE, - mz_method = "addtwins", - ...) { - ped2com( - ped = ped, - max_gen = max_gen, - sparse = sparse, - verbose = verbose, - gc = gc, - component = "additive", - flatten_diag = flatten_diag, - standardize_colnames = standardize_colnames, - transpose_method = transpose_method, - adjacency_method = adjacency_method, - saveable = saveable, - resume = resume, - save_rate_gen = save_rate_gen, - save_rate_parlist = save_rate_parlist, - save_path = save_path, - compress = compress, - mz_twins = mz_twins, - mz_method = mz_method, - ... - ) -} - -#' Take a pedigree and turn it into a mitochondrial relatedness matrix -#' @inheritParams ped2com -#' @inherit ped2com details -#' @export -#' @aliases ped2mt -#' -ped2mit <- ped2mt <- function(ped, max_gen = 25, - sparse = TRUE, - verbose = FALSE, gc = FALSE, - flatten_diag = FALSE, - standardize_colnames = TRUE, - transpose_method = "tcrossprod", - adjacency_method = "direct", - saveable = FALSE, - resume = FALSE, - save_rate = 5, - save_rate_gen = save_rate, - save_rate_parlist = 100000 * save_rate, - save_path = "checkpoint/", - compress = TRUE, - ...) { - ped2com( - ped = ped, - max_gen = max_gen, - sparse = sparse, - verbose = verbose, - gc = gc, - component = "mitochondrial", - flatten_diag = flatten_diag, - standardize_colnames = standardize_colnames, - transpose_method = transpose_method, - adjacency_method = adjacency_method, - saveable = saveable, - resume = resume, - save_rate_gen = save_rate_gen, - save_rate_parlist = save_rate_parlist, - save_path = save_path, - compress = compress, - ... - ) -} - -#' Take a pedigree and turn it into a common nuclear environmental matrix -#' @inheritParams ped2com -#' @inherit ped2com details -#' @export -#' -ped2cn <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, - gc = FALSE, flatten_diag = FALSE, - standardize_colnames = TRUE, - transpose_method = "tcrossprod", - saveable = FALSE, - resume = FALSE, - save_rate = 5, - adjacency_method = "direct", - save_rate_gen = save_rate, - save_rate_parlist = 1000 * save_rate, - save_path = "checkpoint/", - compress = TRUE, - ...) { - ped2com( - ped = ped, - max_gen = max_gen, - sparse = sparse, - verbose = verbose, - gc = gc, - component = "common nuclear", - adjacency_method = adjacency_method, - flatten_diag = flatten_diag, - standardize_colnames = standardize_colnames, - transpose_method = transpose_method, - saveable = saveable, - resume = resume, - save_rate_gen = save_rate_gen, - save_rate_parlist = save_rate_parlist, - save_path = save_path, - compress = compress, - ... - ) -} -#' Take a pedigree and turn it into a generation relatedness matrix -#' @inheritParams ped2com -#' @inherit ped2com details -#' @export -#' -ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, - gc = FALSE, flatten_diag = FALSE, - standardize_colnames = TRUE, - transpose_method = "tcrossprod", - saveable = FALSE, - resume = FALSE, - save_rate = 5, - adjacency_method = "direct", - save_rate_gen = save_rate, - save_rate_parlist = 1000 * save_rate, - save_path = "checkpoint/", - compress = TRUE, - ...) { - ped2com( - ped = ped, - max_gen = max_gen, - sparse = sparse, - verbose = verbose, - gc = gc, - component = "generation", - adjacency_method = adjacency_method, - flatten_diag = flatten_diag, - standardize_colnames = standardize_colnames, - transpose_method = transpose_method, - saveable = saveable, - resume = resume, - save_rate_gen = save_rate_gen, - save_rate_parlist = save_rate_parlist, - save_path = save_path, - compress = compress, - ... - ) -} - - -#' Take a pedigree and turn it into an extended environmental relatedness matrix -#' @inheritParams ped2com -#' @inherit ped2com details -#' @export -#' -ped2ce <- function(ped, ...) { - matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped$ID, ped$ID)) -} - - #' Compute the transpose multiplication for the relatedness matrix #' @inheritParams ped2com #' @inherit ped2com details diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R new file mode 100644 index 00000000..0711d62d --- /dev/null +++ b/R/buildComponentWrappers.R @@ -0,0 +1,173 @@ + +#' Take a pedigree and turn it into an additive genetics relatedness matrix +#' @inheritParams ped2com +#' @inherit ped2com details +#' @export +#' +ped2add <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, + gc = FALSE, + flatten_diag = FALSE, standardize_colnames = TRUE, + transpose_method = "tcrossprod", + adjacency_method = "direct", + saveable = FALSE, + resume = FALSE, + save_rate = 5, + save_rate_gen = save_rate, + save_rate_parlist = 100000 * save_rate, + save_path = "checkpoint/", + compress = TRUE, + mz_twins = FALSE, + mz_method = "addtwins", + ...) { + ped2com( + ped = ped, + max_gen = max_gen, + sparse = sparse, + verbose = verbose, + gc = gc, + component = "additive", + flatten_diag = flatten_diag, + standardize_colnames = standardize_colnames, + transpose_method = transpose_method, + adjacency_method = adjacency_method, + saveable = saveable, + resume = resume, + save_rate_gen = save_rate_gen, + save_rate_parlist = save_rate_parlist, + save_path = save_path, + compress = compress, + mz_twins = mz_twins, + mz_method = mz_method, + ... + ) +} + +#' Take a pedigree and turn it into a mitochondrial relatedness matrix +#' @inheritParams ped2com +#' @inherit ped2com details +#' @export +#' @aliases ped2mt +#' +ped2mit <- ped2mt <- function(ped, max_gen = 25, + sparse = TRUE, + verbose = FALSE, gc = FALSE, + flatten_diag = FALSE, + standardize_colnames = TRUE, + transpose_method = "tcrossprod", + adjacency_method = "direct", + saveable = FALSE, + resume = FALSE, + save_rate = 5, + save_rate_gen = save_rate, + save_rate_parlist = 100000 * save_rate, + save_path = "checkpoint/", + compress = TRUE, + ...) { + ped2com( + ped = ped, + max_gen = max_gen, + sparse = sparse, + verbose = verbose, + gc = gc, + component = "mitochondrial", + flatten_diag = flatten_diag, + standardize_colnames = standardize_colnames, + transpose_method = transpose_method, + adjacency_method = adjacency_method, + saveable = saveable, + resume = resume, + save_rate_gen = save_rate_gen, + save_rate_parlist = save_rate_parlist, + save_path = save_path, + compress = compress, + ... + ) +} + +#' Take a pedigree and turn it into a common nuclear environmental matrix +#' @inheritParams ped2com +#' @inherit ped2com details +#' @export +#' +ped2cn <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, + gc = FALSE, flatten_diag = FALSE, + standardize_colnames = TRUE, + transpose_method = "tcrossprod", + saveable = FALSE, + resume = FALSE, + save_rate = 5, + adjacency_method = "direct", + save_rate_gen = save_rate, + save_rate_parlist = 1000 * save_rate, + save_path = "checkpoint/", + compress = TRUE, + ...) { + ped2com( + ped = ped, + max_gen = max_gen, + sparse = sparse, + verbose = verbose, + gc = gc, + component = "common nuclear", + adjacency_method = adjacency_method, + flatten_diag = flatten_diag, + standardize_colnames = standardize_colnames, + transpose_method = transpose_method, + saveable = saveable, + resume = resume, + save_rate_gen = save_rate_gen, + save_rate_parlist = save_rate_parlist, + save_path = save_path, + compress = compress, + ... + ) +} +#' Take a pedigree and turn it into a generation relatedness matrix +#' @inheritParams ped2com +#' @inherit ped2com details +#' @export +#' +ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, + gc = FALSE, flatten_diag = FALSE, + standardize_colnames = TRUE, + transpose_method = "tcrossprod", + saveable = FALSE, + resume = FALSE, + save_rate = 5, + adjacency_method = "direct", + save_rate_gen = save_rate, + save_rate_parlist = 1000 * save_rate, + save_path = "checkpoint/", + compress = TRUE, + ...) { + ped2com( + ped = ped, + max_gen = max_gen, + sparse = sparse, + verbose = verbose, + gc = gc, + component = "generation", + adjacency_method = adjacency_method, + flatten_diag = flatten_diag, + standardize_colnames = standardize_colnames, + transpose_method = transpose_method, + saveable = saveable, + resume = resume, + save_rate_gen = save_rate_gen, + save_rate_parlist = save_rate_parlist, + save_path = save_path, + compress = compress, + ... + ) +} + + +#' Take a pedigree and turn it into an extended environmental relatedness matrix +#' @inheritParams ped2com +#' @inherit ped2com details +#' @export +#' +ped2ce <- function(ped, ...) { + matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped$ID, ped$ID)) +} + From 6926bff355563a53f4a89316ac30b253a0830523 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 12:50:21 -0400 Subject: [PATCH 03/32] Update buildComponent.R --- R/buildComponent.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 50ae5791..a21d9e2f 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -232,7 +232,13 @@ ped2com <- function(ped, component, # --- Step 2: Compute Relatedness Matrix --- - if (config$resume == TRUE && file.exists(checkpoint_files$r_checkpoint) && + if (config$resume == TRUE && file.exists(checkpoint_files$ram_checkpoint)) { + if (config$verbose == TRUE) cat("Resuming: Loading completed RAM matrix...\n") + r <- readRDS(checkpoint_files$ram_checkpoint) + gen <- rep(0, config$nr) + mtSum <- 0 + count <- 0 + } else if (config$resume == TRUE && file.exists(checkpoint_files$r_checkpoint) && file.exists(checkpoint_files$gen_checkpoint) && file.exists(checkpoint_files$mtSum_checkpoint) && file.exists(checkpoint_files$newIsPar_checkpoint) && From ec23c116a6adf9451bad522ba775aa20569d0a16 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 12:58:51 -0400 Subject: [PATCH 04/32] chunked? --- R/buildComponent.R | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index a21d9e2f..44572c24 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -14,7 +14,8 @@ #' @param save_path character. The path to save the checkpoint files #' @param flatten_diag logical. If TRUE, overwrite the diagonal of the final relatedness matrix with ones #' @param standardize_colnames logical. If TRUE, standardize the column names of the pedigree dataset -#' @param transpose_method character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", or "star" +#' @param transpose_method character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked" +#' @param chunk_size integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000. #' @param adjacency_method character. The method to use for computing the adjacency matrix. Options are "loop", "indexed", direct or beta #' @param isChild_method character. The method to use for computing the isChild matrix. Options are "classic" or "partialparent" #' @param adjBeta_method numeric The method to use for computing the building the adjacency_method matrix when using the "beta" build @@ -34,6 +35,7 @@ ped2com <- function(ped, component, flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + chunk_size = 1000L, adjacency_method = "direct", isChild_method = "partialparent", saveable = FALSE, @@ -353,6 +355,7 @@ ped2com <- function(ped, component, } else { r <- .computeTranspose( r2 = r2, transpose_method = transpose_method, + chunk_size = chunk_size, verbose = config$verbose ) if (config$saveable == TRUE) { @@ -442,15 +445,17 @@ ped2com <- function(ped, component, #' @inherit ped2com details #' @param r2 a relatedness matrix #' -.computeTranspose <- function(r2, transpose_method = "tcrossprod", verbose = FALSE) { +.computeTranspose <- function(r2, transpose_method = "tcrossprod", chunk_size = 1000L, + verbose = FALSE) { valid_methods <- c( "tcrossprod", "crossprod", "star", - "tcross.alt.crossprod", "tcross.alt.star" + "tcross.alt.crossprod", "tcross.alt.star", + "chunked" ) if (!transpose_method %in% valid_methods) { stop("Invalid method specified. Choose from 'tcrossprod', 'crossprod', 'star', 'tcross.alt.crossprod', - or 'tcross.alt.star'.") + 'tcross.alt.star', or 'chunked'.") } # Map aliases to core methods @@ -477,6 +482,27 @@ ped2com <- function(ped, component, "star" = { if (verbose == TRUE) cat("Doing tcrossprod using %*% t(.)\n") r2 %*% t(as.matrix(r2)) + }, + "chunked" = { + n <- nrow(r2) + n_chunks <- ceiling(n / chunk_size) + if (verbose == TRUE) { + cat(sprintf( + "Doing chunked tcrossprod: %d rows, chunk size %d (%d chunks)\n", + n, chunk_size, n_chunks + )) + } + blocks <- vector("list", n_chunks) + for (i in seq_len(n_chunks)) { + row_start <- (i - 1L) * chunk_size + 1L + row_end <- min(i * chunk_size, n) + if (verbose == TRUE) { + cat(sprintf(" chunk %d/%d (rows %d-%d)\n", i, n_chunks, row_start, row_end)) + } + blocks[[i]] <- Matrix::tcrossprod(r2[row_start:row_end, , drop = FALSE], r2) + gc() + } + do.call(rbind, blocks) } ) From fc934ec621e322e9c061ca363fef59a21a6f15b4 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 13:39:25 -0400 Subject: [PATCH 05/32] check that ids match --- R/buildComponent.R | 51 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 44572c24..395e59c3 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -16,6 +16,7 @@ #' @param standardize_colnames logical. If TRUE, standardize the column names of the pedigree dataset #' @param transpose_method character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked" #' @param chunk_size integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000. +#' @param keep_ids character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning. #' @param adjacency_method character. The method to use for computing the adjacency matrix. Options are "loop", "indexed", direct or beta #' @param isChild_method character. The method to use for computing the isChild matrix. Options are "classic" or "partialparent" #' @param adjBeta_method numeric The method to use for computing the building the adjacency_method matrix when using the "beta" build @@ -36,6 +37,7 @@ ped2com <- function(ped, component, standardize_colnames = TRUE, transpose_method = "tcrossprod", chunk_size = 1000L, + keep_ids = NULL, adjacency_method = "direct", isChild_method = "partialparent", saveable = FALSE, @@ -348,21 +350,55 @@ ped2com <- function(ped, component, } # --- Step 4: T crossproduct --- + # Subset rows of r2 to target individuals if requested. + # All columns are kept so dot products use the full ancestry paths. + if (!is.null(keep_ids)) { + idx <- match(keep_ids, rownames(r2)) + missing <- keep_ids[is.na(idx)] + if (length(missing) > 0) { + warning(length(missing), " keep_ids not found in pedigree and will be dropped: ", + paste(head(missing, 5), collapse = ", "), + if (length(missing) > 5) " ..." else "") + } + idx <- idx[!is.na(idx)] + if (config$verbose == TRUE) { + cat(sprintf("Subsetting r2 to %d target individuals before tcrossprod\n", length(idx))) + } + r2 <- r2[idx, , drop = FALSE] + } + + use_tcrossprod_checkpoint <- FALSE if (config$resume == TRUE && file.exists(checkpoint_files$tcrossprod_checkpoint) && config$component != "generation") { - if (config$verbose == TRUE) message("Resuming: Loading tcrossprod...\n") - r <- readRDS(checkpoint_files$tcrossprod_checkpoint) - } else { + saved_keep_ids <- if (file.exists(checkpoint_files$tcrossprod_ids)) { + readRDS(checkpoint_files$tcrossprod_ids) + } else { + NULL + } + if (identical(saved_keep_ids, keep_ids)) { + if (config$verbose == TRUE) message("Resuming: Loading tcrossprod...\n") + r <- readRDS(checkpoint_files$tcrossprod_checkpoint) + use_tcrossprod_checkpoint <- TRUE + } else { + warning( + "tcrossprod checkpoint keep_ids do not match — recomputing.\n", + " saved: ", if (is.null(saved_keep_ids)) "NULL (full pedigree)" else paste(length(saved_keep_ids), "IDs"), "\n", + " expected: ", if (is.null(keep_ids)) "NULL (full pedigree)" else paste(length(keep_ids), "IDs") + ) + } + } + + if (use_tcrossprod_checkpoint == FALSE) { + if (config$saveable == TRUE) { + saveRDS(keep_ids, file = checkpoint_files$tcrossprod_ids, compress = config$compress) + } r <- .computeTranspose( r2 = r2, transpose_method = transpose_method, chunk_size = chunk_size, verbose = config$verbose ) if (config$saveable == TRUE) { - saveRDS(r, - file = checkpoint_files$tcrossprod_checkpoint, - compress = config$compress - ) + saveRDS(r, file = checkpoint_files$tcrossprod_checkpoint, compress = config$compress) } } @@ -548,6 +584,7 @@ initializeCheckpoint <- function(config = list( config$save_path, "tcrossprod_checkpoint.rds" ), + tcrossprod_ids = file.path(config$save_path, "tcrossprod_ids.rds"), count_checkpoint = file.path(config$save_path, "count_checkpoint.rds"), final_matrix = file.path(config$save_path, "final_matrix.rds") ) From dc093c7718ef3bb07340c898869d4f8bf011aad1 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 13:49:43 -0400 Subject: [PATCH 06/32] smarter wrapper --- NEWS.md | 7 +++++++ R/buildComponent.R | 3 ++- R/buildComponentWrappers.R | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 65e70125..0ed00222 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,12 @@ # BGmisc NEWS +# Development version: +* Fixed bug in parList +* Moved wrappers of ped2com to own .R file +* Fixed missing checkpoint for ram_checkpoint +* Try a chunk_size argument for ped2com to reduce memory usage during transpose +* Try filter method for what relatednessed to return + # BGmisc 1.6.0.1 ## CRAN submission * Add OpenMx pedigree model builders and docs diff --git a/R/buildComponent.R b/R/buildComponent.R index 395e59c3..6eabc34a 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -106,7 +106,8 @@ ped2com <- function(ped, component, transpose_method_options <- c( "tcrossprod", "crossprod", "star", - "tcross.alt.crossprod", "tcross.alt.star" + "tcross.alt.crossprod", "tcross.alt.star", + "chunked" ) if (!config$transpose_method %in% transpose_method_options) { diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R index 0711d62d..9d2536f5 100644 --- a/R/buildComponentWrappers.R +++ b/R/buildComponentWrappers.R @@ -8,6 +8,8 @@ ped2add <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, gc = FALSE, flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + chunk_size = 1000L, + keep_ids = NULL, adjacency_method = "direct", saveable = FALSE, resume = FALSE, @@ -29,6 +31,8 @@ ped2add <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, flatten_diag = flatten_diag, standardize_colnames = standardize_colnames, transpose_method = transpose_method, + chunk_size = chunk_size, + keep_ids = keep_ids, adjacency_method = adjacency_method, saveable = saveable, resume = resume, From ef13bdea3239127f7d5a933c814ec8738e70b4f9 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 14:01:26 -0400 Subject: [PATCH 07/32] docs --- R/buildComponent.R | 25 ++++++++++++++----------- man/dot-computeTranspose.Rd | 11 +++++++++-- man/ped2add.Rd | 10 ++++++++-- man/ped2ce.Rd | 2 +- man/ped2cn.Rd | 4 ++-- man/ped2com.Rd | 8 +++++++- man/ped2gen.Rd | 4 ++-- man/ped2mit.Rd | 4 ++-- tests/testthat/test-convertPedigree.R | 2 ++ 9 files changed, 47 insertions(+), 23 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 6eabc34a..13512fbb 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -77,7 +77,10 @@ ped2com <- function(ped, component, component = component, adjBeta_method = adjBeta_method, nr = nrow(ped), - compress = compress + compress = compress, + keep_ids = keep_ids, + mz_method = mz_method, + mz_twins = mz_twins ) @@ -135,7 +138,7 @@ ped2com <- function(ped, component, mz_row_pairs <- NULL mz_id_pairs <- NULL - if (mz_twins == TRUE && "twinID" %in% colnames(ped)) { + if (config$mz_twins == TRUE && "twinID" %in% colnames(ped)) { df_mz <- findMZtwins(ped, verbose = config$verbose, returnIDs = TRUE, @@ -154,7 +157,7 @@ ped2com <- function(ped, component, return(readRDS(checkpoint_files$final_matrix)) } - if (mz_method %in% c("merging") && mz_twins == TRUE && !is.null(mz_row_pairs) && length(mz_row_pairs) > 0 && + if (config$mz_method %in% c("merging") && config$mz_twins == TRUE && !is.null(mz_row_pairs) && length(mz_row_pairs) > 0 && config$component %in% c("additive")) { # replace all MZ twin IDs with the first twin's ID in each pair so they are merged for the path tracing and all subsequent steps. We will copy the values back to the second twin at the end. ped <- fuseTwins(ped = ped, mz_row_pairs = mz_row_pairs, mz_id_pairs = mz_id_pairs, config = config, beta = beta) @@ -326,7 +329,7 @@ ped2com <- function(ped, component, compress = config$compress ) - if (mz_method == "addtwins" && mz_twins == TRUE && !is.null(mz_row_pairs) && length(mz_row_pairs) > 0) { + if (config$mz_method == "addtwins" && config$mz_twins == TRUE && !is.null(mz_row_pairs) && length(mz_row_pairs) > 0) { if (config$verbose == TRUE) { message("MZ twin merging enabled: Will merge MZ twin columns in r2 before tcrossprod") } @@ -353,9 +356,9 @@ ped2com <- function(ped, component, # Subset rows of r2 to target individuals if requested. # All columns are kept so dot products use the full ancestry paths. - if (!is.null(keep_ids)) { - idx <- match(keep_ids, rownames(r2)) - missing <- keep_ids[is.na(idx)] + if (!is.null(config$keep_ids)) { + idx <- match(config$keep_ids, rownames(r2)) + missing <- config$keep_ids[is.na(idx)] if (length(missing) > 0) { warning(length(missing), " keep_ids not found in pedigree and will be dropped: ", paste(head(missing, 5), collapse = ", "), @@ -376,7 +379,7 @@ ped2com <- function(ped, component, } else { NULL } - if (identical(saved_keep_ids, keep_ids)) { + if (identical(saved_keep_ids, config$keep_ids)) { if (config$verbose == TRUE) message("Resuming: Loading tcrossprod...\n") r <- readRDS(checkpoint_files$tcrossprod_checkpoint) use_tcrossprod_checkpoint <- TRUE @@ -384,14 +387,14 @@ ped2com <- function(ped, component, warning( "tcrossprod checkpoint keep_ids do not match — recomputing.\n", " saved: ", if (is.null(saved_keep_ids)) "NULL (full pedigree)" else paste(length(saved_keep_ids), "IDs"), "\n", - " expected: ", if (is.null(keep_ids)) "NULL (full pedigree)" else paste(length(keep_ids), "IDs") + " expected: ", if (is.null(config$keep_ids)) "NULL (full pedigree)" else paste(length(config$keep_ids), "IDs") ) } } if (use_tcrossprod_checkpoint == FALSE) { if (config$saveable == TRUE) { - saveRDS(keep_ids, file = checkpoint_files$tcrossprod_ids, compress = config$compress) + saveRDS(config$keep_ids, file = checkpoint_files$tcrossprod_ids, compress = config$compress) } r <- .computeTranspose( r2 = r2, transpose_method = transpose_method, @@ -403,7 +406,7 @@ ped2com <- function(ped, component, } } - if (mz_method %in% c("merging", "addtwins") && mz_twins == TRUE && config$component %in% c("additive") && !is.null(mz_row_pairs) && length(mz_row_pairs) > 0) { + if (config$mz_method %in% c("merging", "addtwins") && config$mz_twins == TRUE && config$component %in% c("additive") && !is.null(mz_row_pairs) && length(mz_row_pairs) > 0) { # --- Step 4b: Restore MZ twins --- # Copy twin1's row/col to twin2 so both twins appear in the final matrix. if (config$sparse == FALSE) { diff --git a/man/dot-computeTranspose.Rd b/man/dot-computeTranspose.Rd index 4d90dcbc..520f5ec4 100644 --- a/man/dot-computeTranspose.Rd +++ b/man/dot-computeTranspose.Rd @@ -4,12 +4,19 @@ \alias{.computeTranspose} \title{Compute the transpose multiplication for the relatedness matrix} \usage{ -.computeTranspose(r2, transpose_method = "tcrossprod", verbose = FALSE) +.computeTranspose( + r2, + transpose_method = "tcrossprod", + chunk_size = 1000L, + verbose = FALSE +) } \arguments{ \item{r2}{a relatedness matrix} -\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", or "star"} +\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} + +\item{chunk_size}{integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000.} \item{verbose}{logical. If TRUE, print progress through stages of algorithm} } diff --git a/man/ped2add.Rd b/man/ped2add.Rd index 0a08cd09..430eb3bf 100644 --- a/man/ped2add.Rd +++ b/man/ped2add.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/buildComponent.R +% Please edit documentation in R/buildComponentWrappers.R \name{ped2add} \alias{ped2add} \title{Take a pedigree and turn it into an additive genetics relatedness matrix} @@ -13,6 +13,8 @@ ped2add( flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + chunk_size = 1000L, + keep_ids = NULL, adjacency_method = "direct", saveable = FALSE, resume = FALSE, @@ -41,7 +43,11 @@ ped2add( \item{standardize_colnames}{logical. If TRUE, standardize the column names of the pedigree dataset} -\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", or "star"} +\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} + +\item{chunk_size}{integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000.} + +\item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} \item{adjacency_method}{character. The method to use for computing the adjacency matrix. Options are "loop", "indexed", direct or beta} diff --git a/man/ped2ce.Rd b/man/ped2ce.Rd index ed22966a..c29540d4 100644 --- a/man/ped2ce.Rd +++ b/man/ped2ce.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/buildComponent.R +% Please edit documentation in R/buildComponentWrappers.R \name{ped2ce} \alias{ped2ce} \title{Take a pedigree and turn it into an extended environmental relatedness matrix} diff --git a/man/ped2cn.Rd b/man/ped2cn.Rd index aafa5f7e..c3ed3df7 100644 --- a/man/ped2cn.Rd +++ b/man/ped2cn.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/buildComponent.R +% Please edit documentation in R/buildComponentWrappers.R \name{ped2cn} \alias{ped2cn} \title{Take a pedigree and turn it into a common nuclear environmental matrix} @@ -39,7 +39,7 @@ ped2cn( \item{standardize_colnames}{logical. If TRUE, standardize the column names of the pedigree dataset} -\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", or "star"} +\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} \item{saveable}{logical. If TRUE, save the intermediate results to disk} diff --git a/man/ped2com.Rd b/man/ped2com.Rd index dc57cdb7..1c9a0342 100644 --- a/man/ped2com.Rd +++ b/man/ped2com.Rd @@ -14,6 +14,8 @@ ped2com( flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + chunk_size = 1000L, + keep_ids = NULL, adjacency_method = "direct", isChild_method = "partialparent", saveable = FALSE, @@ -48,7 +50,11 @@ ped2com( \item{standardize_colnames}{logical. If TRUE, standardize the column names of the pedigree dataset} -\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", or "star"} +\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} + +\item{chunk_size}{integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000.} + +\item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} \item{adjacency_method}{character. The method to use for computing the adjacency matrix. Options are "loop", "indexed", direct or beta} diff --git a/man/ped2gen.Rd b/man/ped2gen.Rd index d57facbf..f97ff6fe 100644 --- a/man/ped2gen.Rd +++ b/man/ped2gen.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/buildComponent.R +% Please edit documentation in R/buildComponentWrappers.R \name{ped2gen} \alias{ped2gen} \title{Take a pedigree and turn it into a generation relatedness matrix} @@ -39,7 +39,7 @@ ped2gen( \item{standardize_colnames}{logical. If TRUE, standardize the column names of the pedigree dataset} -\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", or "star"} +\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} \item{saveable}{logical. If TRUE, save the intermediate results to disk} diff --git a/man/ped2mit.Rd b/man/ped2mit.Rd index b4992fb9..1db6bd13 100644 --- a/man/ped2mit.Rd +++ b/man/ped2mit.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/buildComponent.R +% Please edit documentation in R/buildComponentWrappers.R \name{ped2mit} \alias{ped2mit} \alias{ped2mt} @@ -40,7 +40,7 @@ ped2mit( \item{standardize_colnames}{logical. If TRUE, standardize the column names of the pedigree dataset} -\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", or "star"} +\item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} \item{adjacency_method}{character. The method to use for computing the adjacency matrix. Options are "loop", "indexed", direct or beta} diff --git a/tests/testthat/test-convertPedigree.R b/tests/testthat/test-convertPedigree.R index 3182875b..f24fc8a0 100644 --- a/tests/testthat/test-convertPedigree.R +++ b/tests/testthat/test-convertPedigree.R @@ -250,6 +250,7 @@ test_that("ped2com handles checkpoint uncompressed saving and resuming", { ram_checkpoint = file.path(save_path, "ram_checkpoint.rds"), r2_checkpoint = file.path(save_path, "r2_checkpoint.rds"), tcrossprod_checkpoint = file.path(save_path, "tcrossprod_checkpoint.rds"), + tcrossprod_ids = file.path(save_path, "tcrossprod_ids.rds"), count_checkpoint = file.path(save_path, "count_checkpoint.rds"), final_matrix = file.path(save_path, "final_matrix.rds") ) @@ -296,6 +297,7 @@ test_that("ped2com handles checkpoint saving and resuming", { ram_checkpoint = file.path(save_path, "ram_checkpoint.rds"), r2_checkpoint = file.path(save_path, "r2_checkpoint.rds"), tcrossprod_checkpoint = file.path(save_path, "tcrossprod_checkpoint.rds"), + tcrossprod_ids = file.path(save_path, "tcrossprod_ids.rds"), count_checkpoint = file.path(save_path, "count_checkpoint.rds"), final_matrix = file.path(save_path, "final_matrix.rds") ) From 956ef18c20265ba8f63b669c16e550e1b840ebbf Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 15:17:21 -0400 Subject: [PATCH 08/32] Update buildComponent.R --- R/buildComponent.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 13512fbb..4ec9b37e 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -377,13 +377,17 @@ ped2com <- function(ped, component, saved_keep_ids <- if (file.exists(checkpoint_files$tcrossprod_ids)) { readRDS(checkpoint_files$tcrossprod_ids) } else { - NULL + saved_keep_ids <- NULL + if(config$verbose == TRUE) { + message("No saved keep_ids found for tcrossprod checkpoint. Expected at: ", checkpoint_files$tcrossprod_ids, "\n") + } } if (identical(saved_keep_ids, config$keep_ids)) { if (config$verbose == TRUE) message("Resuming: Loading tcrossprod...\n") r <- readRDS(checkpoint_files$tcrossprod_checkpoint) use_tcrossprod_checkpoint <- TRUE } else { + use_tcrossprod_checkpoint <- FALSE warning( "tcrossprod checkpoint keep_ids do not match — recomputing.\n", " saved: ", if (is.null(saved_keep_ids)) "NULL (full pedigree)" else paste(length(saved_keep_ids), "IDs"), "\n", From e0d881f443d68d346a0563a914983dd934e71f77 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 15:17:34 -0400 Subject: [PATCH 09/32] Update test-buildComponent.R --- tests/testthat/test-buildComponent.R | 209 +++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 585d7de3..e7d77934 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -295,3 +295,212 @@ deviantions all make sense", { # reconstruct the orginal generation values from generated values of children expect_true(all(df_hazard$min_gen_children[df_hazard$ID %in% founders] - 1 == df_hazard$gen_og[df_hazard$ID %in% founders])) }) + +# ── ram_checkpoint ──────────────────────────────────────────────────────────── + +test_that("resume loads ram_checkpoint and skips RAM loop when mid-loop files absent", { + data(hazard) + save_path <- file.path(tempdir(), "test_ram_checkpoint") + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + # First run: save all checkpoints + r_full <- ped2com(hazard, component = "additive", sparse = FALSE, + saveable = TRUE, resume = FALSE, + save_rate_gen = 1, save_path = save_path) + + # Remove mid-loop files so only ram_checkpoint (and earlier) remain + mid_loop_files <- c("r_checkpoint.rds", "gen_checkpoint.rds", + "mtSum_checkpoint.rds", "newIsPar_checkpoint.rds", + "count_checkpoint.rds") + file.remove(file.path(save_path, mid_loop_files)) + + expect_true(file.exists(file.path(save_path, "ram_checkpoint.rds"))) + expect_false(file.exists(file.path(save_path, "r_checkpoint.rds"))) + + # Second run: should load ram_checkpoint, skip loop, and produce same result + r_resumed <- ped2com(hazard, component = "additive", sparse = FALSE, + saveable = FALSE, resume = TRUE, + save_path = save_path) + + expect_equal(r_full, r_resumed) +}) + +test_that("ram_checkpoint resume produces identical result to fresh run", { + data(hazard) + save_path <- file.path(tempdir(), "test_ram_idempotent") + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + r_fresh <- ped2com(hazard, component = "additive", sparse = FALSE, + saveable = TRUE, resume = FALSE, + save_rate_gen = 1, save_path = save_path) + + file.remove(file.path(save_path, "r_checkpoint.rds")) + file.remove(file.path(save_path, "tcrossprod_checkpoint.rds")) + + r_resumed <- ped2com(hazard, component = "additive", sparse = FALSE, + saveable = FALSE, resume = TRUE, + save_path = save_path) + + expect_equal(r_fresh, r_resumed, tolerance = 1e-10) +}) + +# ── keep_ids ────────────────────────────────────────────────────────────────── + +test_that("keep_ids subset produces correct relatedness values", { + data(hazard) + keep <- as.character(hazard$ID[5:10]) + + r_full <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL) + r_sub <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) +}) + +test_that("keep_ids with unknown IDs warns and drops missing entries", { + data(hazard) + keep <- c(as.character(hazard$ID[1:3]), "BOGUS_ID") + + expect_warning( + r_sub <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep), + "keep_ids not found" + ) + expect_equal(nrow(r_sub), 3L) +}) + +test_that("keep_ids = NULL returns full pedigree matrix", { + data(hazard) + r_full <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL) + expect_equal(nrow(r_full), nrow(hazard)) +}) + +# ── chunked tcrossprod ──────────────────────────────────────────────────────── + +test_that("chunked tcrossprod matches standard tcrossprod", { + data(hazard) + r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "tcrossprod") + r_chunked <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = 3L) + + expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) +}) + +test_that("chunked tcrossprod with chunk_size >= nrow behaves like tcrossprod", { + data(hazard) + r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "tcrossprod") + r_chunked <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", + chunk_size = nrow(hazard) + 1L) + + expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) +}) + +# ── tcrossprod_ids checkpoint validation ────────────────────────────────────── + +test_that("tcrossprod checkpoint is reused when keep_ids matches saved ids", { + data(hazard) + keep <- as.character(hazard$ID[1:5]) + save_path <- file.path(tempdir(), "test_tcp_ids_match") + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + # First run: saves tcrossprod_checkpoint and tcrossprod_ids + r1 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep, saveable = TRUE, resume = FALSE, + save_path = save_path) + + expect_true(file.exists(file.path(save_path, "tcrossprod_ids.rds"))) + expect_equal(readRDS(file.path(save_path, "tcrossprod_ids.rds")), keep) + + # Second run: same keep_ids → should load checkpoint, not recompute + r2 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep, saveable = FALSE, resume = TRUE, + save_path = save_path) + + expect_equal(r1, r2) +}) + +test_that("tcrossprod checkpoint is recomputed with warning when keep_ids changes", { + data(hazard) + keep1 <- as.character(hazard$ID[1:5]) + keep2 <- as.character(hazard$ID[6:10]) + save_path <- file.path(tempdir(), "test_tcp_ids_mismatch") + unlink(save_path, recursive = TRUE) # guarantee clean state + dir.create(save_path, showWarnings = FALSE) + + + ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep1, saveable = TRUE, resume = FALSE, + save_path = save_path) + + # verify the setup saved what we expect before testing the warning + expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) + expect_equal(readRDS(file.path(save_path, "tcrossprod_ids.rds")), keep1) + + unlink(file.path(save_path, "final_matrix.rds")) # ensure we're testing the checkpoint loading, not final matrix loading + + + expect_warning( + r2 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep2, saveable = FALSE, resume = TRUE,verbose = TRUE, + save_path = save_path), + "keep_ids do not match" + ) + expect_equal(rownames(r2), keep2) + on.exit(unlink(save_path, recursive = TRUE)) +}) + +test_that("tcrossprod checkpoint saved with keep_ids=NULL is reused on NULL resume", { + data(hazard) + save_path <- file.path(tempdir(), "test_tcp_ids_null") + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + r1 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = TRUE, resume = FALSE, + save_path = save_path) + + expect_null(readRDS(file.path(save_path, "tcrossprod_ids.rds"))) + + r2 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = FALSE, resume = TRUE, + save_path = save_path) + + expect_equal(r1, r2) +}) + +test_that("tcrossprod checkpoint saved with NULL warns when resumed with keep_ids", { + data(hazard) + keep <- as.character(hazard$ID[1:5]) + save_path <- file.path(tempdir(), "test_tcp_ids_null_mismatch") + unlink(save_path, recursive = TRUE) # guarantee clean state + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = TRUE, resume = FALSE, + save_path = save_path) + + # verify the setup saved what we expect before testing the warning + expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) + expect_null(readRDS(file.path(save_path, "tcrossprod_ids.rds"))) + unlink(file.path(save_path, "final_matrix.rds")) # ensure we're testing the checkpoint loading, not final matrix loading + + expect_warning( + ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep, saveable = FALSE, resume = TRUE, + save_path = save_path), + "keep_ids do not match" + ) +}) From f9b009624289b7f2a75c0a677e37d437bf4d9399 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 17:45:10 -0400 Subject: [PATCH 10/32] tests --- R/buildComponent.R | 29 +- R/buildComponentWrappers.R | 13 +- data-raw/optimizing_transpose.R | 371 +++++++++++++++++ data-raw/ped2com_benchmark_design_com.csv | 25 ++ data-raw/ped2com_benchmark_end_time.txt | 2 +- data-raw/ped2com_benchmark_results.csv | 482 +++++++++++----------- data-raw/ped2com_benchmark_start_time.txt | 2 +- data-raw/ped2com_benchmark_summary.csv | 30 +- tests/testthat/test-buildComponent.R | 63 +++ 9 files changed, 754 insertions(+), 263 deletions(-) create mode 100644 data-raw/optimizing_transpose.R create mode 100644 data-raw/ped2com_benchmark_design_com.csv diff --git a/R/buildComponent.R b/R/buildComponent.R index 4ec9b37e..71452591 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -23,6 +23,7 @@ #' @param compress logical. If TRUE, use compression when saving the checkpoint files. Defaults to TRUE. #' @param mz_twins logical. If TRUE, merge MZ co-twin columns in the r2 matrix before tcrossprod so that MZ twins are coded with relatedness 1 instead of 0.5. Twin pairs are identified from the \code{twinID} column. When a \code{zygosity} column is also present, only pairs where both members have \code{zygosity == "MZ"} are used; otherwise all \code{twinID} pairs are assumed to be MZ. Defaults to FALSE. #' @param mz_method character. The method to handle MZ twins. Options are "merging" (default) or "addtwins". "addtwins" adds the twin2 column to the twin1 column before tcrossprod so that all relatedness flows through a single source, then leaves the twin2 column as zero and relies on the fact that the row/col names are the same to copy the values back to twin2 after tcrossprod. "merging" merges the twin2 column into the twin1 column before tcrossprod and then copies the values back to twin2 after tcrossprod so that both twins appear in the final matrix. +#' @param force_symmetric logical. If TRUE, force the final relatedness matrix to be symmetric. This can help mitigate any numerical asymmetry introduced by the transpose method, especially when using sparse matrices. Defaults to TRUE. #' @param beta logical. Used for benchmarking #' @param ... additional arguments to be passed to \code{\link{ped2com}} #' @details The algorithms and methodologies used in this function are further discussed and exemplified in the vignette titled "examplePedigreeFunctions". For more advanced scenarios and detailed explanations, consult this vignette. @@ -52,6 +53,7 @@ ped2com <- function(ped, component, mz_twins = TRUE, mz_method = "addtwins", beta = FALSE, + force_symmetric = FALSE, ...) { #------ # Check inputs @@ -80,7 +82,8 @@ ped2com <- function(ped, component, compress = compress, keep_ids = keep_ids, mz_method = mz_method, - mz_twins = mz_twins + mz_twins = mz_twins, + force_symmetric = force_symmetric ) @@ -401,9 +404,11 @@ ped2com <- function(ped, component, saveRDS(config$keep_ids, file = checkpoint_files$tcrossprod_ids, compress = config$compress) } r <- .computeTranspose( - r2 = r2, transpose_method = transpose_method, + r2 = r2, + transpose_method = transpose_method, chunk_size = chunk_size, - verbose = config$verbose + verbose = config$verbose, + force_symmetric = config$force_symmetric ) if (config$saveable == TRUE) { saveRDS(r, file = checkpoint_files$tcrossprod_checkpoint, compress = config$compress) @@ -488,9 +493,12 @@ ped2com <- function(ped, component, #' @inheritParams ped2com #' @inherit ped2com details #' @param r2 a relatedness matrix +#' @param force_symmetric logical. If TRUE, forces the output matrix to be symmetric using Matrix::forceSymmetric. This can be helpful when using chunked multiplication to ensure the final result is exactly symmetric despite potential numerical issues. Defaults to TRUE. #' .computeTranspose <- function(r2, transpose_method = "tcrossprod", chunk_size = 1000L, - verbose = FALSE) { + verbose = FALSE, force_symmetric = FALSE, config = NULL, + checkpoint_files = NULL + ) { valid_methods <- c( "tcrossprod", "crossprod", "star", "tcross.alt.crossprod", "tcross.alt.star", @@ -543,14 +551,25 @@ ped2com <- function(ped, component, if (verbose == TRUE) { cat(sprintf(" chunk %d/%d (rows %d-%d)\n", i, n_chunks, row_start, row_end)) } + + if(resum blocks[[i]] <- Matrix::tcrossprod(r2[row_start:row_end, , drop = FALSE], r2) gc() + + if(saveable == TRUE && (i %% save_rate_parlist == 0)) { + saveRDS(blocks[[i]], file = paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds"), compress = config$compress) + } } + do.call(rbind, blocks) + } ) - + if(force_symmetric == TRUE) { + Matrix:::forceSymmetric(result) + } else { result + } } #' Initialize checkpoint files diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R index 9d2536f5..ee510fdc 100644 --- a/R/buildComponentWrappers.R +++ b/R/buildComponentWrappers.R @@ -20,6 +20,7 @@ ped2add <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, compress = TRUE, mz_twins = FALSE, mz_method = "addtwins", + force_symmetric = FALSE, ...) { ped2com( ped = ped, @@ -42,6 +43,7 @@ ped2add <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, compress = compress, mz_twins = mz_twins, mz_method = mz_method, + force_symmetric = force_symmetric, ... ) } @@ -66,6 +68,7 @@ ped2mit <- ped2mt <- function(ped, max_gen = 25, save_rate_parlist = 100000 * save_rate, save_path = "checkpoint/", compress = TRUE, + force_symmetric = FALSE, ...) { ped2com( ped = ped, @@ -84,6 +87,7 @@ ped2mit <- ped2mt <- function(ped, max_gen = 25, save_rate_parlist = save_rate_parlist, save_path = save_path, compress = compress, + force_symmetric = force_symmetric, ... ) } @@ -105,6 +109,7 @@ ped2cn <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, save_rate_parlist = 1000 * save_rate, save_path = "checkpoint/", compress = TRUE, + force_symmetric = FALSE, ...) { ped2com( ped = ped, @@ -123,6 +128,7 @@ ped2cn <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, save_rate_parlist = save_rate_parlist, save_path = save_path, compress = compress, + force_symmetric = force_symmetric, ... ) } @@ -143,6 +149,7 @@ ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, save_rate_parlist = 1000 * save_rate, save_path = "checkpoint/", compress = TRUE, + force_symmetric = FALSE, ...) { ped2com( ped = ped, @@ -161,6 +168,7 @@ ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, save_rate_parlist = save_rate_parlist, save_path = save_path, compress = compress, + force_symmetric = force_symmetric, ... ) } @@ -171,7 +179,8 @@ ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, #' @inherit ped2com details #' @export #' -ped2ce <- function(ped, ...) { - matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped$ID, ped$ID)) +ped2ce <- function(ped, personID = "ID", + ...) { + matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped[[personID]], ped[[personID]])) } diff --git a/data-raw/optimizing_transpose.R b/data-raw/optimizing_transpose.R new file mode 100644 index 00000000..a2aaacc3 --- /dev/null +++ b/data-raw/optimizing_transpose.R @@ -0,0 +1,371 @@ +library(profvis) +library(microbenchmark) +library(tidyverse) +devtools::load_all(".") + + +# --------------------------- +# 0) Config +# --------------------------- +cfg <- list( + seed = 1164127, + Ngen_base = 2, + reps = 10, + all_scenarios = TRUE, # set to TRUE to run all scenarios defined below + include_highgen = TRUE, + include_1gen = FALSE, + include_lowgen = FALSE +) +cfg$gen_twin <- ceiling(cfg$Ngen_base - 1) + +set.seed(cfg$seed) + +# --------------------------- +# 1) Levels (edit here to extend) +# --------------------------- +levels <- list( + ped = tibble( + ped_label = c( + if (cfg$include_1gen) "1gen", + if (cfg$include_lowgen) "lowgen", + "midgen", + if (cfg$include_highgen) "highgen" + ), + Ngen_total = c( + if (cfg$include_1gen) 1, + if (cfg$include_lowgen) cfg$Ngen_base, + cfg$Ngen_base * 2, + if (cfg$include_highgen) cfg$Ngen_base * 3 + ), + gen_twin = c( + if (cfg$include_1gen) 1, + if (cfg$include_lowgen) cfg$gen_twin, + cfg$gen_twin, + if (cfg$include_highgen) cfg$gen_twin + ) + # Add highgen row whenever you want + ), + + # Simulation-side factors (simulatePedigree) + kpc = 5, # set to c(2, 3, 4) to vary + sexR = 0.50, # sometimes fails above .5 + marR = c(0.9), # set to c(0.6, 0.8, 0.9) to vary + sim_beta = TRUE, # set to c(TRUE, FALSE) if you ever want to vary + + # Conversion-side factors (ped2com) + component = c("additive"), + transpose_method = c("tcrossprod", "crossprod", "star", + "chunked"), + twin_method = c("NULL"), + beta = c(TRUE), + sparse_matrix = c(FALSE, TRUE) # user-facing name, translated to ped2com's `sparse` +) + +# Which columns define a unique simulation vs conversion condition +# If you add a new factor, put its name in the right scope here. + +scopes <- list( + sim = c("ped_label", "Ngen_total", "gen_twin", "kpc", "sexR", "marR", "sim_beta"), + conv = c("component", "twin_method", "beta", "sparse_matrix", "transpose_method") +) + +# --------------------------- +# 2) Scenarios (edit here to control crossing) +# --------------------------- +# Each scenario says what to vary and what to fix. No other code changes. +scenarios <- list( + full = list( + vary = c("ped", "marR", "twin_method", "beta", "sparse_matrix","transpose_method"), + fixed = list() + ), + quick = list( + vary = c("ped", "twin_method","transpose_method"), + fixed = list(marR = 0.8, beta = FALSE, sparse_matrix = TRUE, component = "additive") + ) + + # Add more scenarios whenever you want: + # e.g., "marR_only" = list(vary=c("marR"), fixed=list(ped = levels$ped[levels$ped$ped_label=="midgen",], ...)) +) + +if (!cfg$all_scenarios) { + scenarios <- scenarios[c("full")] # order control; also, comment out any you don't want to run +} +# --------------------------- +# 3) Generic design builder (do not edit to add factors) +# --------------------------- +`%||%` <- function(x, y) if (!is.null(x)) x else y + +level_tbl <- function(name, x) { + if (inherits(x, "data.frame")) { + return(x) + } + tibble(!!name := x) +} + +default_value <- function(x) { + if (inherits(x, "data.frame")) { + return(x[1, , drop = FALSE]) + } + x[[1]] +} + +expand_scenario <- function(levels, vary, fixed = list(), scenario = "scenario") { + df <- tibble(.dummy = 1) + + # expand varied factors + for (nm in vary) { + df <- tidyr::crossing(df, level_tbl(nm, levels[[nm]])) + } + + # add fixed/default factors not varied + not_varied <- setdiff(names(levels), vary) + for (nm in not_varied) { + lv <- levels[[nm]] + + if (inherits(lv, "data.frame")) { + const <- fixed[[nm]] %||% default_value(lv) + if (!inherits(const, "data.frame") || nrow(const) != 1) const <- default_value(lv) + df <- bind_cols(df, const[rep(1, nrow(df)), , drop = FALSE]) + } else { + df[[nm]] <- fixed[[nm]] %||% default_value(lv) + } + } + + df %>% + select(-.dummy) %>% + mutate(scenario = scenario, .before = 1) +} + +build_design <- function(levels, scenarios) { + purrr::imap_dfr( + scenarios, + ~ expand_scenario(levels, vary = .x$vary, fixed = .x$fixed, scenario = .y) + ) +} + +design <- build_design(levels, scenarios) + +# Create a stable, joinable label (also becomes the microbenchmark expr name) +design <- design %>% + mutate( + label = paste0( + scenario, + "|ped=", ped_label, + "|marR=", marR, + "|twin=", twin_method, + "|trans=", transpose_method, + "|beta=", beta, + "|sparse=", sparse_matrix, + "|comp=", component + ) + ) + +# --------------------------- +# 4) Simulation cache (simulate once per unique sim condition) +# --------------------------- +simulate_one <- function(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta,fam_shift=1) { + simulatePedigree( + kpc = kpc, Ngen = Ngen_total, sexR = sexR, marR = marR, + fam_shift = fam_shift, + beta = sim_beta + ) %>% + makeTwins(gen_twin = gen_twin) +} + +simulate_many <- function(number_of_families, + Ngen_total, gen_twin, kpc, sexR, marR, sim_beta) { + replicate(simulate_one(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta,fam_shift = 1 + ), number_of_families, simplify = FALSE) +} + + + +sim_tbl <- design %>% + distinct(across(all_of(scopes$sim))) %>% + mutate( + sim_id = row_number(), + ped = pmap( + list(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta, sim_id), + function(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta, sim_id) { + set.seed(cfg$seed + sim_id) + simulate_one(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta) + } + ) + ) %>% + select(-sim_id) + +design <- design %>% left_join(sim_tbl, by = scopes$sim) + +# Put peds and args in keyed lists so benchmark expressions stay tiny +peds_by_label <- setNames(design$ped, design$label) + +# --------------------------- +# 5) Conversion arg translation (edit only if you add non-1:1 args) +# --------------------------- +# Columns that map directly to ped2com arg names go through automatically. +# Anything else gets a translation rule here. +special_to_args <- list( + twin_method = function(v) { + if (is.null(v) || length(v) == 0 || is.na(v) || v == "NULL") { + list(mz_twins = FALSE) + } else { + list(mz_twins = TRUE, mz_method = v) + } + }, + beta = function(v) list(beta = v), + sparse_matrix = function(v) list(sparse = v) +) + +make_conv_args <- function(row, conv_cols) { + # row is already a named list of scalar values when called correctly + direct_cols <- setdiff(conv_cols, names(special_to_args)) + args <- row[direct_cols] + + for (nm in intersect(names(special_to_args), conv_cols)) { + args <- c(args, special_to_args[[nm]](row[[nm]])) + } + + args +} + +make_conv_args_row <- function(...) { + row <- list(...) + make_conv_args(row, scopes$conv) +} + +# Correct per-row args creation +args_by_label <- design %>% + mutate( + conv_args = pmap(select(., all_of(scopes$conv)), make_conv_args_row) + ) %>% + select(label, conv_args) %>% + deframe() + +# --------------------------- +# 6) One microbenchmark call with all expressions (correct behavior) +# --------------------------- +bench_exprs <- lapply(names(peds_by_label), function(lbl) { + bquote( + do.call(ped2com, c(list(ped = peds_by_label[[.(lbl)]]), args_by_label[[.(lbl)]])) + ) +}) +names(bench_exprs) <- names(peds_by_label) + +write_csv(design, "data-raw/ped2com_benchmark_design_com.csv") +# write start time +write.table(Sys.time(), "data-raw/ped2com_benchmark_start_time.txt", row.names = FALSE, col.names = FALSE) + + +benchmark_results <- do.call( + microbenchmark::microbenchmark, + c(bench_exprs, list(times = cfg$reps)) +) + +write.table(Sys.time(), "data-raw/ped2com_benchmark_end_time.txt", row.names = FALSE, col.names = FALSE) + +results <- as_tibble(benchmark_results) %>% + mutate(label = as.character(expr)) %>% + left_join( + design %>% select(-ped), + by = "label" + ) +# notes: sparse with addtwins is slow (878 vs 250), but sparse with merging is way times slower (14257 vs 241). This is a huge difference, and suggests that the merging method is not compatible with sparse matrices in its current form. The addtwins method is slower than NULL in both cases, but the difference is much more pronounced when using sparse matrices. The means of adding or substituting twins in the pedigree may interact with the way sparse matrices are constructed or handled in ped2com, leading to increased computational overhead. The NULL method is the fastest in both cases, which is expected since it does not involve any additional processing for twins. Overall, these results suggest that while the addtwins method can be used with sparse matrices, it may not be the most efficient choice, and the merging method may not be suitable for use with sparse matrices at all. +# --------------------------- +# 7) Analysis/plot +# --------------------------- +results <- results %>% + mutate( + twin_method = factor(twin_method, levels = c("NULL", "addtwins", "merging")), + transpose_method = factor( + transpose_method, + levels = c( + "tcrossprod", + "crossprod", + "star", + "tcross.alt.crossprod", + "tcross.alt.star", + "chunked" + ) + ), + ped_label = factor(ped_label, levels = levels$ped$ped_label), + gen_factor = factor(ped_label, levels = levels$ped$ped_label, + labels = paste0(levels$ped$Ngen_total, " gen")) + ) +write_csv(results, "data-raw/ped2com_benchmark_results.csv") + +summary(results) +results %>% + group_by(ped_label, transpose_method, twin_method, sparse_matrix) %>% + summarise( + median_time_ms = median(time / 1e6), + mean_time_ms = mean(time / 1e6), + var_time_ms = var(time / 1e6), + sd_time_ms = sd(time / 1e6), + se_time_ms = sd(time / 1e6) / sqrt(n()), + n_time = n(), + .groups = "drop_last" + ) %>% + arrange(ped_label, twin_method, sparse_matrix) %>% + write_csv("data-raw/ped2com_benchmark_summary.csv") + +# ped_label twin_method sparse_matrix median_time_ms +# +# 7 highgen NULL FALSE 222. +# 8 highgen NULL TRUE 198. +# 9 highgen addtwins FALSE 250. +# 10 highgen addtwins TRUE 878. +# 11 highgen merging FALSE 241. +# 12 highgen merging TRUE 14257. + +if (cfg$reps > 8) { + notch <- FALSE +} else { + notch <- FALSE +} + +results %>% + # dplyr::filter(!ped_label %in% c("1gen", "lowgen", "midgen")) %>% + mutate( + beta_sparse = paste0("beta=", beta, ", sparse=", sparse_matrix), + beta_sparse = factor(beta_sparse, levels = c( + "beta=FALSE, sparse=FALSE", + "beta=FALSE, sparse=TRUE", + "beta=TRUE, sparse=FALSE", + "beta=TRUE, sparse=TRUE" + )) + ) %>% + ggplot( + aes( + x = ped_label, + y = time / 1e6, + fill = transpose_method, + color = sparse_matrix # , + # shape = beta + ) + ) + + geom_boxplot( + notch = notch, position = position_dodge(width = 0.8), outlier.size = 0.5, + linewidth = 0.25 + ) + + scale_y_log10() + + # facet_grid(~scenario) + + labs( + title = "Benchmarking ped2com() by transpose method", + x = "Pedigree", + y = "Execution time (ms)", + color = "sparse_matrix", + fill = "Transpose method" + ) + + theme_minimal() + +# scale_fill_manual(values = c( +# "beta=FALSE, sparse=FALSE" = "lightgray", +# "beta=FALSE, sparse=TRUE" = "gray8", +# "beta=TRUE, sparse=FALSE" = "lightcoral", +# "beta=TRUE, sparse=TRUE" = "red2" +# )) + + scale_color_manual(values = c("FALSE" = "gray", "TRUE" = "black")) + #c("NULL" = "gray", "addtwins" = "skyblue3", "merging" = "tomato2")) +# df <- sim_tbl$ped[[2]] + +# df_add <- df %>% ped2add() + diff --git a/data-raw/ped2com_benchmark_design_com.csv b/data-raw/ped2com_benchmark_design_com.csv new file mode 100644 index 00000000..e33f11d2 --- /dev/null +++ b/data-raw/ped2com_benchmark_design_com.csv @@ -0,0 +1,25 @@ +scenario,ped_label,Ngen_total,gen_twin,marR,twin_method,beta,sparse_matrix,transpose_method,kpc,sexR,sim_beta,component,label,ped +full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive, +full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive, +full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive, +full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive, +full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive, +full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive, +full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive, +full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive, +full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive, +quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive, +quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive, +quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive, +quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive, +quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive, +quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive, +quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive, +quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive, diff --git a/data-raw/ped2com_benchmark_end_time.txt b/data-raw/ped2com_benchmark_end_time.txt index ae7f71ae..14848412 100644 --- a/data-raw/ped2com_benchmark_end_time.txt +++ b/data-raw/ped2com_benchmark_end_time.txt @@ -1 +1 @@ -2026-02-16 10:47:50.923385 +2026-03-24 17:17:17.056999 diff --git a/data-raw/ped2com_benchmark_results.csv b/data-raw/ped2com_benchmark_results.csv index c26e7302..f5f75ad7 100644 --- a/data-raw/ped2com_benchmark_results.csv +++ b/data-raw/ped2com_benchmark_results.csv @@ -1,241 +1,241 @@ -expr,time,label,scenario,ped_label,Ngen_total,gen_twin,marR,twin_method,beta,sparse_matrix,kpc,sexR,sim_beta,component,gen_factor -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,1097588100,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,1427187500,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,208481200,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,6189200,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,200689000,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,27103200,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,40300200,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,6026000,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,227563000,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,7928900,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,205996300,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,7277200,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,7109900,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,238252400,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,8026300,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,286128500,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,1445191500,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,1254251600,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,6127200,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,10656600,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,9625200,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,8027400,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,11509500,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,7426000,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,443970200,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,241512000,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,452599400,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,11105000,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,7619100,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,244079300,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,902782300,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,454902600,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,234666900,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,7181500,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,8527000,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,212780500,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,1100157100,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,231629800,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,245438700,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,9059000,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,214617000,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,6712400,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,445690600,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,235071900,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,253957100,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,1028123600,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,10129800,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,232238800,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,399899300,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,266978400,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,12141300,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,7296500,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,262951300,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,8368100,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,8787900,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,13507800,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,7670000,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,261880300,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,420694500,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,6956400,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,10659100,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,6674800,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,415774000,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,7061000,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,8168300,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,12491500,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,859762100,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,10746300,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,7435100,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,10309000,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,1154719100,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,686766200,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,8156100,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,1250916100,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,720033600,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,227784000,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,210911700,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,8514700,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,209204900,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,456020500,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,14974900,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,13465800,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,194586400,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,226957000,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,182487000,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,8091400,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,666622800,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,7738000,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,7558800,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,506063000,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,428734800,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,8621300,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,11728100,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,12375600,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,8772300,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,12003600,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,824795700,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,7323800,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,245685100,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,417243300,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,9535600,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,7172700,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,7072900,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,8495100,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,238015500,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,7356900,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,515113200,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,703907500,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,7065900,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,7029700,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,223874400,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,234624100,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,10971500,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,9505400,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,8480900,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,701840500,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,8603400,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,1366937400,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,12457400,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,7429200,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,221505800,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,8338300,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,7587900,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,260293200,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,6970500,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,387071800,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,7560700,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,7024200,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,7572400,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,679198200,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,7570400,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,8952100,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,220476700,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,1324076900,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,870241700,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,236028200,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,241456900,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,6418900,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,193984200,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,174968700,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,9338700,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,237393900,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,8107300,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,7594300,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,214633800,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,223070000,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,1162039400,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,6900500,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,9390800,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,6822900,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,6129800,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,419321700,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,239979200,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,246306700,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,413186000,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,945828200,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,212045300,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,516998700,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,7050200,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,185658200,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,195559600,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,10013400,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,244554400,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,10914100,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,260740500,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,696082600,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,991407800,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,183159200,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,250327800,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,11682700,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,972089100,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,7223900,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,7554000,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,248708600,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,414717900,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,234125500,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,185366000,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,1164331700,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,192493700,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,1004205400,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,409725900,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,9967800,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,7054100,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,7931100,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,9482300,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,240506300,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,178059100,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,9036700,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,8792900,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,515438000,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,7878200,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,6172500,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,678646600,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,12139500,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,705609800,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,10250500,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,8626400,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,669870100,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,8373900,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,7465900,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,7766100,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,8029300,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,9360000,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,8011500,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,5451100,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,181073500,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,708658700,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,458115900,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,212310700,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,6463400,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,1134949700,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,10318000,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,6561300,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,415959500,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,10837000,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,253422200,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,11325500,full|ped=midgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,498453800,full|ped=highgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,6816400,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,9532900,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,7317400,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,815704200,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,8478700,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,7668400,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,189231300,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,970275100,full|ped=highgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,FALSE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,224921500,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,823923000,full|ped=highgen|marR=0.8|twin=addtwins|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,9,2,0.8,addtwins,TRUE,TRUE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,8553200,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,203815400,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,8441500,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,239606300,full|ped=highgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,434145700,full|ped=highgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,7041200,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,7063600,full|ped=midgen|marR=0.8|twin=merging|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,206283600,full|ped=highgen|marR=0.8|twin=NULL|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,9,2,0.8,NULL,TRUE,FALSE,3,0.5,TRUE,additive,9 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,6966300,full|ped=midgen|marR=0.8|twin=NULL|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,NULL,FALSE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,6370100,full|ped=midgen|marR=0.8|twin=NULL|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,6,2,0.8,NULL,TRUE,TRUE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,6395900,full|ped=midgen|marR=0.8|twin=merging|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,merging,TRUE,FALSE,3,0.5,TRUE,additive,6 gen -full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,7256300,full|ped=midgen|marR=0.8|twin=addtwins|beta=FALSE|sparse=FALSE|comp=additive,full,midgen,6,2,0.8,addtwins,FALSE,FALSE,3,0.5,TRUE,additive,6 gen +expr,time,label,scenario,ped_label,Ngen_total,gen_twin,marR,twin_method,beta,sparse_matrix,transpose_method,kpc,sexR,sim_beta,component,gen_factor +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,1426885500,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,5074400,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,335998400,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,5277700,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,4505100,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,169840600,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,102792700,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,84370100,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,6530100,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1659836400,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,5035000,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,1023202700,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,226468900,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,4260000,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,7797072500,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,470552600,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,4192300,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,1088327200,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,1053376100,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,5337100,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,416517100,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,4548100,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,4682800,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,299694600,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,8272869700,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,592600800,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,111375900,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,252973000,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,385089200,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,5384700,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,1065617700,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,413004500,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,5756100,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,5229100,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,5525700,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,294594800,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,480760300,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,211596400,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,205670000,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,5571200,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,5032300,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,348860300,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,5420700,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,468334400,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,7919969600,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,5029500,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,4909100,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,3708800,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,3897300,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,213507300,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,207947900,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,4300400,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,3718300,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,87267700,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,1167126100,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,4733600,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,9288940700,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,79190500,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,5837700,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,5404700,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,9206709900,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,5336100,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,270050500,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,343689800,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,4427900,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,212009300,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,5426600,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,4870400,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,221715800,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,5468100,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,1224729100,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,956696900,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,352861200,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,284170200,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,4406600,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,939938500,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,83067900,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,7123500,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,213405200,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,241527500,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,4477300,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,8149993300,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,458632000,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1764958200,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,5053200,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1689521300,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,7822845100,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,221552000,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,979419300,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,4685800,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1858349200,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,53262900,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,5587300,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,4757100,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,213037000,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,4531300,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,967428500,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,212358100,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,5025800,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,4019900,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,156609700,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,202290300,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,197341300,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,4676400,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,7990473100,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,992609100,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,8347362700,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,226131300,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,4454800,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1652447700,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,5612000,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,5216000,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,7985670000,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,264263100,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1669509900,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,5200700,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,5094800,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,4946500,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,220582900,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,541883500,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,6000400,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,1012808700,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,8313805100,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,8517411600,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,4692600,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,214752500,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,91307900,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,5025000,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,93125400,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,231096200,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,4662800,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,4515200,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,169182600,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,4618100,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,8530761100,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,1012108300,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,5328100,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,4747800,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,5903000,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,282967300,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,270742600,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,986350800,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,84618100,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,4961200,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,1136478500,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,550326400,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,5018100,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,224609700,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,8816529300,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,8192747700,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,88824300,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,4982900,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,4284800,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,242331400,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,199432000,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,88321400,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,465789300,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1730057100,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,504732400,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,207010100,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,4856400,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,4191500,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,974285300,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,4689500,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,472618700,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,205272800,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,205523700,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,4754500,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,944462800,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,76236500,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,106387100,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,218325200,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,4846600,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,205742900,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,8024878200,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,4510000,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,4674100,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,1040511000,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,4359600,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,1890982700,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,219297900,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,210726900,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,4897800,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,8249201700,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,156795200,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,290181800,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,146893200,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,5621700,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,4188600,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,477003900,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,212787700,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,5324900,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,4895700,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,4510200,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,165185600,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,10239830000,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,8668200,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,6329300,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,6499500,quick|ped=midgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,6684300,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,720349900,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,379686400,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,3002100200,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,14934294900,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,138111300,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,1858727700,full|ped=highgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,587538500,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,10312500,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,13077600,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,11114000,full|ped=midgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,420369500,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,353704400,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,7796800,quick|ped=midgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,386794300,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,8250800,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,6686400,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,393465200,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,869833300,quick|ped=highgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,7372700,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,375710700,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,820229800,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,385340800,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,354114800,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,337113200,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,354613500,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,7254300,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,6433200,full|ped=midgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,4 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,6397400,quick|ped=midgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,4 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,335489000,full|ped=midgen|marR=0.9|twin=NULL|trans=chunked|beta=TRUE|sparse=FALSE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,FALSE,chunked,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,14394208400,full|ped=highgen|marR=0.9|twin=NULL|trans=crossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,145934500,quick|ped=highgen|marR=0.8|twin=NULL|trans=star|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,star,5,0.5,TRUE,additive,6 gen +quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,360494900,quick|ped=midgen|marR=0.8|twin=NULL|trans=chunked|beta=FALSE|sparse=TRUE|comp=additive,quick,midgen,4,1,0.8,NULL,FALSE,TRUE,chunked,5,0.5,TRUE,additive,4 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,135756500,quick|ped=highgen|marR=0.8|twin=NULL|trans=tcrossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,335247400,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,334665300,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,8019400,full|ped=midgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,midgen,4,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,4 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,795434900,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=FALSE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,FALSE,star,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,338143100,full|ped=highgen|marR=0.9|twin=NULL|trans=tcrossprod|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,tcrossprod,5,0.5,TRUE,additive,6 gen +full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,349964300,full|ped=highgen|marR=0.9|twin=NULL|trans=star|beta=TRUE|sparse=TRUE|comp=additive,full,highgen,6,1,0.9,NULL,TRUE,TRUE,star,5,0.5,TRUE,additive,6 gen +quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,3353313300,quick|ped=highgen|marR=0.8|twin=NULL|trans=crossprod|beta=FALSE|sparse=TRUE|comp=additive,quick,highgen,6,1,0.8,NULL,FALSE,TRUE,crossprod,5,0.5,TRUE,additive,6 gen diff --git a/data-raw/ped2com_benchmark_start_time.txt b/data-raw/ped2com_benchmark_start_time.txt index 91c3edb0..fd996736 100644 --- a/data-raw/ped2com_benchmark_start_time.txt +++ b/data-raw/ped2com_benchmark_start_time.txt @@ -1 +1 @@ -2026-02-16 10:46:51.927423 +2026-03-24 17:13:03.813783 diff --git a/data-raw/ped2com_benchmark_summary.csv b/data-raw/ped2com_benchmark_summary.csv index 5fd17eb4..075567bf 100644 --- a/data-raw/ped2com_benchmark_summary.csv +++ b/data-raw/ped2com_benchmark_summary.csv @@ -1,13 +1,17 @@ -ped_label,twin_method,sparse_matrix,median_time_ms,mean_time_ms,var_time_ms,sd_time_ms,se_time_ms,n_time -midgen,NULL,FALSE,7.08545,7.065175,0.38096159250000006,0.6172208620097024,0.13801478045847118,20 -midgen,NULL,TRUE,7.010350000000001,6.97651,0.3269079230526316,0.5717586230680143,0.1278491147901759,20 -midgen,addtwins,FALSE,8.371,8.478245,1.852214922605263,1.360961029054566,0.30432013756940757,20 -midgen,addtwins,TRUE,11.5961,12.25093,13.742667178000001,3.7071103541707524,0.8289350752019123,20 -midgen,merging,FALSE,7.703200000000001,7.761935,0.6603589255526314,0.81262471384559265,0.18170841003550597,20 -midgen,merging,TRUE,9.5205,11.184985,48.470337688710515,6.962064183035841,1.556764877698468,20 -highgen,NULL,FALSE,225.3165,243.54288,3892.258395726947,62.38796675423031,13.950373464045589,20 -highgen,NULL,TRUE,194.2853,214.36891,3924.8415531188416,62.648555874168736,14.008642962683505,20 -highgen,addtwins,FALSE,261.08675,315.74309,9358.837543218842,96.74108508394374,21.631964246478915,20 -highgen,addtwins,TRUE,1081.53665,1098.186765,40060.529971101336,200.15126772294332,44.75518404112608,20 -highgen,merging,FALSE,253.68965,307.289225,7715.235275696711,87.83641201515867,19.640818816557406,20 -highgen,merging,TRUE,691.4244,704.852615,29254.359534471863,171.03905850557018,38.24549616260185,20 +ped_label,transpose_method,twin_method,sparse_matrix,median_time_ms,mean_time_ms,var_time_ms,sd_time_ms,se_time_ms,n_time +midgen,tcrossprod,NULL,FALSE,4.93945,5.11683,0.2797832534444443,0.5289454163185879,0.16726722734727334,10 +midgen,crossprod,NULL,FALSE,5.370900000000001,6.6615400000000005,8.505323102666669,2.9163887091172653,0.9222430863208826,10 +midgen,star,NULL,FALSE,4.674300000000001,5.30903,3.596578326777778,1.896464691677063,0.599714792778849,10 +midgen,chunked,NULL,FALSE,223.08085,269.55476,6578.876636484889,81.11027454327157,25.64932091983117,10 +midgen,tcrossprod,NULL,TRUE,4.9014500000000005,5.39162,1.7443511869473685,1.3207388791685388,0.29532619143477334,20 +midgen,crossprod,NULL,TRUE,5.18625,5.262435,0.5507754202894738,0.7421424528279418,0.1659480973511709,20 +midgen,star,NULL,TRUE,5.0391,5.365115,1.6761157487105263,1.2946488901283337,0.2894922925321611,20 +midgen,chunked,NULL,TRUE,222.71460000000002,273.110345,10436.315157175237,102.15828481907494,22.843286932023634,20 +highgen,tcrossprod,NULL,FALSE,291.93240000000003,376.72697999999997,31190.325831915106,176.6078306075784,55.84829973411465,10 +highgen,crossprod,NULL,FALSE,8261.0357,8299.29164,142360.10276114484,377.3063778431857,119.31475296925557,10 +highgen,star,NULL,FALSE,365.1621,376.14641,49107.74115759433,221.60266505074873,70.07691571237588,10 +highgen,chunked,NULL,FALSE,1012.4585,1076.72633,21849.292908426785,147.81506319866992,46.7432272189531,10 +highgen,tcrossprod,NULL,TRUE,208.86849999999998,191.22562,9397.38121283537,96.94009084396079,21.676463287210126,20 +highgen,crossprod,NULL,TRUE,5575.1929,5913.68671,19461576.336318098,4411.527664689194,986.4475742865936,20 +highgen,star,NULL,TRUE,160.9904,205.14430000000002,14301.410492077895,119.588504849245,26.740802617047503,20 +highgen,chunked,NULL,TRUE,904.8859,825.28217,126886.80174856324,356.21173724143796,79.65136588551486,20 diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index e7d77934..5b49c2f5 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -362,6 +362,19 @@ test_that("keep_ids subset produces correct relatedness values", { # values in the subset must match the corresponding entries of the full matrix expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + + + r_full <- ped2com(hazard, component = "additive", sparse = T, + keep_ids = NULL) + r_sub <- ped2com(hazard, component = "additive", sparse = T, + keep_ids = keep) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + }) test_that("keep_ids with unknown IDs warns and drops missing entries", { @@ -393,6 +406,28 @@ test_that("chunked tcrossprod matches standard tcrossprod", { transpose_method = "chunked", chunk_size = 3L) expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) + expect_equal(r_standard, r_chunked, tolerance = 1e-10) + + + data(inbreeding) + r_standard <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "tcrossprod") + r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L,force_symmetric = FALSE) + + r_chunked_sym <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L,force_symmetric = TRUE) + + expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) + + expect_equal(r_standard, + r_chunked + # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision + , tolerance = 1e-10) + expect_equal(r_standard, + r_chunked_sym + # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision + , tolerance = 1e-10) }) test_that("chunked tcrossprod with chunk_size >= nrow behaves like tcrossprod", { @@ -406,6 +441,34 @@ test_that("chunked tcrossprod with chunk_size >= nrow behaves like tcrossprod", expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) }) + + + +test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", { + data(inbreeding) + + keep <- as.character(inbreeding$ID[5:10]) + + r_full <- ped2com(inbreeding, component = "additive", sparse = T, + keep_ids = NULL) + r_sub <- ped2com(inbreeding, component = "additive", sparse = T, + keep_ids = keep) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + + r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L,keep_ids = keep) + + expect_equal(as.matrix(r_sub), as.matrix(r_chunked), tolerance = 1e-10) + expect_equal(r_sub, r_chunked, tolerance = 1e-10) + expect_equal(r_full[keep, keep], r_chunked, tolerance = 1e-10) + +}) + # ── tcrossprod_ids checkpoint validation ────────────────────────────────────── test_that("tcrossprod checkpoint is reused when keep_ids matches saved ids", { From 8f4276b2c485276842ad87853ea8586e50f2cc30 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 18:00:51 -0400 Subject: [PATCH 11/32] resume chunks --- R/buildComponent.R | 11 ++++++++--- tests/testthat/test-buildComponent.R | 12 +++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 71452591..f233c363 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -408,7 +408,8 @@ ped2com <- function(ped, component, transpose_method = transpose_method, chunk_size = chunk_size, verbose = config$verbose, - force_symmetric = config$force_symmetric + force_symmetric = config$force_symmetric, + config = config ) if (config$saveable == TRUE) { saveRDS(r, file = checkpoint_files$tcrossprod_checkpoint, compress = config$compress) @@ -552,11 +553,15 @@ ped2com <- function(ped, component, cat(sprintf(" chunk %d/%d (rows %d-%d)\n", i, n_chunks, row_start, row_end)) } - if(resum + if(config$resume == TRUE && file.exists(paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds"))) { + if (verbose == TRUE) cat(" Resuming: Loading chunk from checkpoint...\n") + blocks[[i]] <- readRDS(paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds")) + next + } blocks[[i]] <- Matrix::tcrossprod(r2[row_start:row_end, , drop = FALSE], r2) gc() - if(saveable == TRUE && (i %% save_rate_parlist == 0)) { + if(config$saveable == TRUE) { saveRDS(blocks[[i]], file = paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds"), compress = config$compress) } } diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 5b49c2f5..39dac2ee 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -420,10 +420,12 @@ test_that("chunked tcrossprod matches standard tcrossprod", { expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) - expect_equal(r_standard, - r_chunked - # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision - , tolerance = 1e-10) + expect_gt(# size of matrix in gb r_chunked should be bigger than r_standard due to chunking overhead + object.size(r_chunked) / 1e9, + object.size(r_standard) / 1e9) + + expect_equal(Matrix:::forceSymmetric(r_chunked), + r_chunked_sym, tolerance = 1e-10) expect_equal(r_standard, r_chunked_sym # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision @@ -461,7 +463,7 @@ test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "chunked", chunk_size = 3L,keep_ids = keep) + transpose_method = "chunked", chunk_size = 3L,keep_ids = keep,force_symmetric = T) expect_equal(as.matrix(r_sub), as.matrix(r_chunked), tolerance = 1e-10) expect_equal(r_sub, r_chunked, tolerance = 1e-10) From 91c3952a0d9aec01cfc338efeed391dd88013100 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 18:08:55 -0400 Subject: [PATCH 12/32] Add force_symmetric option and docs --- R/buildComponent.R | 12 +++++++----- man/dot-computeTranspose.Rd | 7 ++++++- man/ped2add.Rd | 3 +++ man/ped2ce.Rd | 2 +- man/ped2cn.Rd | 3 +++ man/ped2com.Rd | 3 +++ man/ped2gen.Rd | 3 +++ man/ped2mit.Rd | 3 +++ 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index f233c363..04eb7a5e 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -566,15 +566,17 @@ ped2com <- function(ped, component, } } - do.call(rbind, blocks) + if(force_symmetric == TRUE) { + Matrix:::forceSymmetric( do.call(rbind, blocks)) + } else { + do.call(rbind, blocks) + } } ) - if(force_symmetric == TRUE) { - Matrix:::forceSymmetric(result) - } else { + result - } + } #' Initialize checkpoint files diff --git a/man/dot-computeTranspose.Rd b/man/dot-computeTranspose.Rd index 520f5ec4..e0d7b040 100644 --- a/man/dot-computeTranspose.Rd +++ b/man/dot-computeTranspose.Rd @@ -8,7 +8,10 @@ r2, transpose_method = "tcrossprod", chunk_size = 1000L, - verbose = FALSE + verbose = FALSE, + force_symmetric = FALSE, + config = NULL, + checkpoint_files = NULL ) } \arguments{ @@ -19,6 +22,8 @@ \item{chunk_size}{integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000.} \item{verbose}{logical. If TRUE, print progress through stages of algorithm} + +\item{force_symmetric}{logical. If TRUE, forces the output matrix to be symmetric using Matrix::forceSymmetric. This can be helpful when using chunked multiplication to ensure the final result is exactly symmetric despite potential numerical issues. Defaults to TRUE.} } \description{ Compute the transpose multiplication for the relatedness matrix diff --git a/man/ped2add.Rd b/man/ped2add.Rd index 430eb3bf..e0e875cd 100644 --- a/man/ped2add.Rd +++ b/man/ped2add.Rd @@ -25,6 +25,7 @@ ped2add( compress = TRUE, mz_twins = FALSE, mz_method = "addtwins", + force_symmetric = FALSE, ... ) } @@ -69,6 +70,8 @@ ped2add( \item{mz_method}{character. The method to handle MZ twins. Options are "merging" (default) or "addtwins". "addtwins" adds the twin2 column to the twin1 column before tcrossprod so that all relatedness flows through a single source, then leaves the twin2 column as zero and relies on the fact that the row/col names are the same to copy the values back to twin2 after tcrossprod. "merging" merges the twin2 column into the twin1 column before tcrossprod and then copies the values back to twin2 after tcrossprod so that both twins appear in the final matrix.} +\item{force_symmetric}{logical. If TRUE, force the final relatedness matrix to be symmetric. This can help mitigate any numerical asymmetry introduced by the transpose method, especially when using sparse matrices. Defaults to TRUE.} + \item{...}{additional arguments to be passed to \code{\link{ped2com}}} } \description{ diff --git a/man/ped2ce.Rd b/man/ped2ce.Rd index c29540d4..514841b3 100644 --- a/man/ped2ce.Rd +++ b/man/ped2ce.Rd @@ -4,7 +4,7 @@ \alias{ped2ce} \title{Take a pedigree and turn it into an extended environmental relatedness matrix} \usage{ -ped2ce(ped, ...) +ped2ce(ped, personID = "ID", ...) } \arguments{ \item{ped}{a pedigree dataset. Needs ID, momID, and dadID columns} diff --git a/man/ped2cn.Rd b/man/ped2cn.Rd index c3ed3df7..1bfe548b 100644 --- a/man/ped2cn.Rd +++ b/man/ped2cn.Rd @@ -21,6 +21,7 @@ ped2cn( save_rate_parlist = 1000 * save_rate, save_path = "checkpoint/", compress = TRUE, + force_symmetric = FALSE, ... ) } @@ -57,6 +58,8 @@ ped2cn( \item{compress}{logical. If TRUE, use compression when saving the checkpoint files. Defaults to TRUE.} +\item{force_symmetric}{logical. If TRUE, force the final relatedness matrix to be symmetric. This can help mitigate any numerical asymmetry introduced by the transpose method, especially when using sparse matrices. Defaults to TRUE.} + \item{...}{additional arguments to be passed to \code{\link{ped2com}}} } \description{ diff --git a/man/ped2com.Rd b/man/ped2com.Rd index 1c9a0342..2795e5dd 100644 --- a/man/ped2com.Rd +++ b/man/ped2com.Rd @@ -30,6 +30,7 @@ ped2com( mz_twins = TRUE, mz_method = "addtwins", beta = FALSE, + force_symmetric = FALSE, ... ) } @@ -84,6 +85,8 @@ ped2com( \item{beta}{logical. Used for benchmarking} +\item{force_symmetric}{logical. If TRUE, force the final relatedness matrix to be symmetric. This can help mitigate any numerical asymmetry introduced by the transpose method, especially when using sparse matrices. Defaults to TRUE.} + \item{...}{additional arguments to be passed to \code{\link{ped2com}}} } \description{ diff --git a/man/ped2gen.Rd b/man/ped2gen.Rd index f97ff6fe..ec9feef5 100644 --- a/man/ped2gen.Rd +++ b/man/ped2gen.Rd @@ -21,6 +21,7 @@ ped2gen( save_rate_parlist = 1000 * save_rate, save_path = "checkpoint/", compress = TRUE, + force_symmetric = FALSE, ... ) } @@ -57,6 +58,8 @@ ped2gen( \item{compress}{logical. If TRUE, use compression when saving the checkpoint files. Defaults to TRUE.} +\item{force_symmetric}{logical. If TRUE, force the final relatedness matrix to be symmetric. This can help mitigate any numerical asymmetry introduced by the transpose method, especially when using sparse matrices. Defaults to TRUE.} + \item{...}{additional arguments to be passed to \code{\link{ped2com}}} } \description{ diff --git a/man/ped2mit.Rd b/man/ped2mit.Rd index 1db6bd13..81db86c0 100644 --- a/man/ped2mit.Rd +++ b/man/ped2mit.Rd @@ -22,6 +22,7 @@ ped2mit( save_rate_parlist = 1e+05 * save_rate, save_path = "checkpoint/", compress = TRUE, + force_symmetric = FALSE, ... ) } @@ -58,6 +59,8 @@ ped2mit( \item{compress}{logical. If TRUE, use compression when saving the checkpoint files. Defaults to TRUE.} +\item{force_symmetric}{logical. If TRUE, force the final relatedness matrix to be symmetric. This can help mitigate any numerical asymmetry introduced by the transpose method, especially when using sparse matrices. Defaults to TRUE.} + \item{...}{additional arguments to be passed to \code{\link{ped2com}}} } \description{ From ae7c6812167ed1fefee33acad474ee94735744d7 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 20:28:56 -0400 Subject: [PATCH 13/32] moving chunk tests --- R/buildComponent.R | 17 +- tests/testthat/test-buildComponent.R | 172 ----------- tests/testthat/test-buildComponent_chunks.R | 308 ++++++++++++++++++++ 3 files changed, 323 insertions(+), 174 deletions(-) create mode 100644 tests/testthat/test-buildComponent_chunks.R diff --git a/R/buildComponent.R b/R/buildComponent.R index 04eb7a5e..aece5547 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -15,7 +15,7 @@ #' @param flatten_diag logical. If TRUE, overwrite the diagonal of the final relatedness matrix with ones #' @param standardize_colnames logical. If TRUE, standardize the column names of the pedigree dataset #' @param transpose_method character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked" -#' @param chunk_size integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000. +#' @param chunk_size numeric. If greater than 1 is Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000. If less than or equal to 1, the entire matrix is processed in a single chunk. #' @param keep_ids character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning. #' @param adjacency_method character. The method to use for computing the adjacency matrix. Options are "loop", "indexed", direct or beta #' @param isChild_method character. The method to use for computing the isChild matrix. Options are "classic" or "partialparent" @@ -409,7 +409,8 @@ ped2com <- function(ped, component, chunk_size = chunk_size, verbose = config$verbose, force_symmetric = config$force_symmetric, - config = config + config = config, + checkpoint_files = if (exists("checkpoint_files")) checkpoint_files else NULL ) if (config$saveable == TRUE) { saveRDS(r, file = checkpoint_files$tcrossprod_checkpoint, compress = config$compress) @@ -517,6 +518,15 @@ ped2com <- function(ped, component, "tcross.alt.star" = "star" ) + if(chunk_size>1){ + chunk_size_method <- "lines" + } else if (chunk_size > 0 && chunk_size <= 1) { + chunk_size_method <- "proportion" + } else { + chunk_size_method <- "full" + } + + if (transpose_method %in% names(alias_map)) { method_normalized <- alias_map[[transpose_method]] } else { @@ -538,6 +548,9 @@ ped2com <- function(ped, component, }, "chunked" = { n <- nrow(r2) + if (chunk_size_method == "proportion") { + chunk_size <- ceiling(n * chunk_size) + } n_chunks <- ceiling(n / chunk_size) if (verbose == TRUE) { cat(sprintf( diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 39dac2ee..4b26e14f 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -396,176 +396,4 @@ test_that("keep_ids = NULL returns full pedigree matrix", { expect_equal(nrow(r_full), nrow(hazard)) }) -# ── chunked tcrossprod ──────────────────────────────────────────────────────── -test_that("chunked tcrossprod matches standard tcrossprod", { - data(hazard) - r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "tcrossprod") - r_chunked <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = 3L) - - expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) - expect_equal(r_standard, r_chunked, tolerance = 1e-10) - - - data(inbreeding) - r_standard <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "tcrossprod") - r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "chunked", chunk_size = 3L,force_symmetric = FALSE) - - r_chunked_sym <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "chunked", chunk_size = 3L,force_symmetric = TRUE) - - expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) - - expect_gt(# size of matrix in gb r_chunked should be bigger than r_standard due to chunking overhead - object.size(r_chunked) / 1e9, - object.size(r_standard) / 1e9) - - expect_equal(Matrix:::forceSymmetric(r_chunked), - r_chunked_sym, tolerance = 1e-10) - expect_equal(r_standard, - r_chunked_sym - # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision - , tolerance = 1e-10) -}) - -test_that("chunked tcrossprod with chunk_size >= nrow behaves like tcrossprod", { - data(hazard) - r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "tcrossprod") - r_chunked <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", - chunk_size = nrow(hazard) + 1L) - - expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) -}) - - - - -test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", { - data(inbreeding) - - keep <- as.character(inbreeding$ID[5:10]) - - r_full <- ped2com(inbreeding, component = "additive", sparse = T, - keep_ids = NULL) - r_sub <- ped2com(inbreeding, component = "additive", sparse = T, - keep_ids = keep) - - expect_equal(dim(r_sub), c(length(keep), length(keep))) - expect_equal(rownames(r_sub), keep) - - # values in the subset must match the corresponding entries of the full matrix - expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) - - r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "chunked", chunk_size = 3L,keep_ids = keep,force_symmetric = T) - - expect_equal(as.matrix(r_sub), as.matrix(r_chunked), tolerance = 1e-10) - expect_equal(r_sub, r_chunked, tolerance = 1e-10) - expect_equal(r_full[keep, keep], r_chunked, tolerance = 1e-10) - -}) - -# ── tcrossprod_ids checkpoint validation ────────────────────────────────────── - -test_that("tcrossprod checkpoint is reused when keep_ids matches saved ids", { - data(hazard) - keep <- as.character(hazard$ID[1:5]) - save_path <- file.path(tempdir(), "test_tcp_ids_match") - dir.create(save_path, showWarnings = FALSE) - on.exit(unlink(save_path, recursive = TRUE)) - - # First run: saves tcrossprod_checkpoint and tcrossprod_ids - r1 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep, saveable = TRUE, resume = FALSE, - save_path = save_path) - - expect_true(file.exists(file.path(save_path, "tcrossprod_ids.rds"))) - expect_equal(readRDS(file.path(save_path, "tcrossprod_ids.rds")), keep) - - # Second run: same keep_ids → should load checkpoint, not recompute - r2 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep, saveable = FALSE, resume = TRUE, - save_path = save_path) - - expect_equal(r1, r2) -}) - -test_that("tcrossprod checkpoint is recomputed with warning when keep_ids changes", { - data(hazard) - keep1 <- as.character(hazard$ID[1:5]) - keep2 <- as.character(hazard$ID[6:10]) - save_path <- file.path(tempdir(), "test_tcp_ids_mismatch") - unlink(save_path, recursive = TRUE) # guarantee clean state - dir.create(save_path, showWarnings = FALSE) - - - ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep1, saveable = TRUE, resume = FALSE, - save_path = save_path) - - # verify the setup saved what we expect before testing the warning - expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) - expect_equal(readRDS(file.path(save_path, "tcrossprod_ids.rds")), keep1) - - unlink(file.path(save_path, "final_matrix.rds")) # ensure we're testing the checkpoint loading, not final matrix loading - - - expect_warning( - r2 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep2, saveable = FALSE, resume = TRUE,verbose = TRUE, - save_path = save_path), - "keep_ids do not match" - ) - expect_equal(rownames(r2), keep2) - on.exit(unlink(save_path, recursive = TRUE)) -}) - -test_that("tcrossprod checkpoint saved with keep_ids=NULL is reused on NULL resume", { - data(hazard) - save_path <- file.path(tempdir(), "test_tcp_ids_null") - dir.create(save_path, showWarnings = FALSE) - on.exit(unlink(save_path, recursive = TRUE)) - - r1 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL, saveable = TRUE, resume = FALSE, - save_path = save_path) - - expect_null(readRDS(file.path(save_path, "tcrossprod_ids.rds"))) - - r2 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL, saveable = FALSE, resume = TRUE, - save_path = save_path) - - expect_equal(r1, r2) -}) - -test_that("tcrossprod checkpoint saved with NULL warns when resumed with keep_ids", { - data(hazard) - keep <- as.character(hazard$ID[1:5]) - save_path <- file.path(tempdir(), "test_tcp_ids_null_mismatch") - unlink(save_path, recursive = TRUE) # guarantee clean state - dir.create(save_path, showWarnings = FALSE) - on.exit(unlink(save_path, recursive = TRUE)) - - ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL, saveable = TRUE, resume = FALSE, - save_path = save_path) - - # verify the setup saved what we expect before testing the warning - expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) - expect_null(readRDS(file.path(save_path, "tcrossprod_ids.rds"))) - unlink(file.path(save_path, "final_matrix.rds")) # ensure we're testing the checkpoint loading, not final matrix loading - - expect_warning( - ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep, saveable = FALSE, resume = TRUE, - save_path = save_path), - "keep_ids do not match" - ) -}) diff --git a/tests/testthat/test-buildComponent_chunks.R b/tests/testthat/test-buildComponent_chunks.R new file mode 100644 index 00000000..fdb08bb8 --- /dev/null +++ b/tests/testthat/test-buildComponent_chunks.R @@ -0,0 +1,308 @@ + +# ── chunked tcrossprod per-chunk checkpointing ─────────────────────────────── + +# Helper: chunk file path matching production code +chunk_path <- function(save_path, i) { + paste0(file.path(save_path, "tcrossprod_checkpoint.rds"), "_chunk_", i, ".rds") +} +# ── chunked tcrossprod ──────────────────────────────────────────────────────── + +test_that("chunked tcrossprod matches standard tcrossprod", { + data(hazard) + r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "tcrossprod") + r_chunked_line <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = 3L) + + r_chunked_prop <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = .5) + + r_chunked <- r_chunked_prop + expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) + expect_equal(r_standard, r_chunked, tolerance = 1e-10) + + r_chunked <- r_chunked_line + expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) + expect_equal(r_standard, r_chunked, tolerance = 1e-10) + + data(inbreeding) + r_standard <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "tcrossprod") + r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L,force_symmetric = FALSE) + + r_chunked_sym <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L,force_symmetric = TRUE) + + expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) + + expect_gt(# size of matrix in gb r_chunked should be bigger than r_standard due to chunking overhead + object.size(r_chunked) / 1e9, + object.size(r_standard) / 1e9) + + expect_equal(Matrix:::forceSymmetric(r_chunked), + r_chunked_sym, tolerance = 1e-10) + expect_equal(r_standard, + r_chunked_sym + # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision + , tolerance = 1e-10) +}) + +test_that("chunked tcrossprod with chunk_size >= nrow behaves like tcrossprod", { + data(hazard) + r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "tcrossprod") + r_chunked <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", + chunk_size = nrow(hazard) + 1L) + + expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) +}) + + + +test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", { + data(inbreeding) + + keep <- as.character(inbreeding$ID[5:10]) + + r_full <- ped2com(inbreeding, component = "additive", sparse = T, + keep_ids = NULL) + r_sub <- ped2com(inbreeding, component = "additive", sparse = T, + keep_ids = keep) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + + r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L, + keep_ids = keep,force_symmetric = T) + + expect_equal(as.matrix(r_sub), as.matrix(r_chunked), tolerance = 1e-10) + expect_equal(r_sub, r_chunked, tolerance = 1e-10) + expect_equal(r_full[keep, keep], r_chunked, tolerance = 1e-10) + +}) +test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and size is line-based", { + data(hazard) + save_path <- file.path(tempdir(), "test_chunk_save") + unlink(save_path, recursive = TRUE) + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + chunk_size <- 3L + r_full <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path) + + n_chunks <- ceiling(nrow(r_full) / chunk_size) + for (i in seq_len(n_chunks)) { + expect_true(file.exists(chunk_path(save_path, i)), + info = paste("chunk file", i, "should exist")) + } +}) + +test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and size is propoportion", { + data(hazard) + save_path <- file.path(tempdir(), "test_chunk_save") + unlink(save_path, recursive = TRUE) + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + chunk_size <- .3 + r_full <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path) + + n_chunks <- ceiling(nrow(r_full)*chunk_size) + for (i in seq_len(n_chunks)) { + expect_true(file.exists(chunk_path(save_path, i)), + info = paste("chunk file", i, "should exist")) + } +}) + + +test_that("chunked tcrossprod resumes from all saved chunk files", { + data(hazard) + save_path <- file.path(tempdir(), "test_chunk_resume_all") + unlink(save_path, recursive = TRUE) + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + chunk_size <- 3L + + r1 <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path) + + # Remove assembled checkpoint so resume must reconstruct from chunk files + unlink(file.path(save_path, "tcrossprod_checkpoint.rds")) + unlink(file.path(save_path, "final_matrix.rds")) + + r2 <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = FALSE, resume = TRUE, save_path = save_path) + + expect_equal(as.matrix(r1), as.matrix(r2), tolerance = 1e-10) +}) + +test_that("chunked tcrossprod partial resume recomputes missing chunks and gives correct result", { + data(hazard) + save_path <- file.path(tempdir(), "test_chunk_resume_partial") + unlink(save_path, recursive = TRUE) + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + chunk_size <- 3L + + r_reference <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path) + + n_chunks <- ceiling(nrow(r_reference) / chunk_size) + + # Delete even-numbered chunks to simulate an interrupted run + for (i in seq(2, n_chunks, by = 2)) unlink(chunk_path(save_path, i)) + unlink(file.path(save_path, "tcrossprod_checkpoint.rds")) + unlink(file.path(save_path, "final_matrix.rds")) + + r_partial <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = FALSE, resume = TRUE, save_path = save_path) + + expect_equal(as.matrix(r_reference), as.matrix(r_partial), tolerance = 1e-10) +}) + +test_that("chunked tcrossprod resume loads chunk files not recompute them", { + data(hazard) + save_path <- file.path(tempdir(), "test_chunk_load_proof") + unlink(save_path, recursive = TRUE) + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + chunk_size <- 3L + + ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path) + + # Replace chunk 1 with a sentinel (all zeros) to prove it gets loaded not recomputed + sentinel <- readRDS(chunk_path(save_path, 1)) * 0 + saveRDS(sentinel, file = chunk_path(save_path, 1)) + + unlink(file.path(save_path, "tcrossprod_checkpoint.rds")) + unlink(file.path(save_path, "final_matrix.rds")) + + r_resumed <- ped2com(hazard, component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = FALSE, resume = TRUE, save_path = save_path) + + # Rows from chunk 1 must be all-zero (loaded from sentinel) + expect_true(all(as.matrix(r_resumed)[1:chunk_size, ] == 0), + info = "rows from chunk 1 should be all-zero (sentinel)") + # Rows from chunk 2 must be non-zero (computed normally) + expect_true(any(as.matrix(r_resumed)[chunk_size + 1L, ] != 0), + info = "rows from chunk 2 should be non-zero") +}) + +# ── tcrossprod_ids checkpoint validation ────────────────────────────────────── + +test_that("tcrossprod checkpoint is reused when keep_ids matches saved ids", { + data(hazard) + keep <- as.character(hazard$ID[1:5]) + save_path <- file.path(tempdir(), "test_tcp_ids_match") + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + # First run: saves tcrossprod_checkpoint and tcrossprod_ids + r1 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep, saveable = TRUE, resume = FALSE, + save_path = save_path) + + expect_true(file.exists(file.path(save_path, "tcrossprod_ids.rds"))) + expect_equal(readRDS(file.path(save_path, "tcrossprod_ids.rds")), keep) + + # Second run: same keep_ids → should load checkpoint, not recompute + r2 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep, saveable = FALSE, resume = TRUE, + save_path = save_path) + + expect_equal(r1, r2) +}) + +test_that("tcrossprod checkpoint is recomputed with warning when keep_ids changes", { + data(hazard) + keep1 <- as.character(hazard$ID[1:5]) + keep2 <- as.character(hazard$ID[6:10]) + save_path <- file.path(tempdir(), "test_tcp_ids_mismatch") + unlink(save_path, recursive = TRUE) # guarantee clean state + dir.create(save_path, showWarnings = FALSE) + + + ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep1, saveable = TRUE, resume = FALSE, + save_path = save_path) + + # verify the setup saved what we expect before testing the warning + expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) + expect_equal(readRDS(file.path(save_path, "tcrossprod_ids.rds")), keep1) + + unlink(file.path(save_path, "final_matrix.rds")) # ensure we're testing the checkpoint loading, not final matrix loading + + + expect_warning( + r2 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep2, saveable = FALSE, resume = TRUE,verbose = TRUE, + save_path = save_path), + "keep_ids do not match" + ) + expect_equal(rownames(r2), keep2) + on.exit(unlink(save_path, recursive = TRUE)) +}) + +test_that("tcrossprod checkpoint saved with keep_ids=NULL is reused on NULL resume", { + data(hazard) + save_path <- file.path(tempdir(), "test_tcp_ids_null") + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + r1 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = TRUE, resume = FALSE, + save_path = save_path) + + expect_null(readRDS(file.path(save_path, "tcrossprod_ids.rds"))) + + r2 <- ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = FALSE, resume = TRUE, + save_path = save_path) + + expect_equal(r1, r2) +}) + +test_that("tcrossprod checkpoint saved with NULL warns when resumed with keep_ids", { + data(hazard) + keep <- as.character(hazard$ID[1:5]) + save_path <- file.path(tempdir(), "test_tcp_ids_null_mismatch") + unlink(save_path, recursive = TRUE) # guarantee clean state + dir.create(save_path, showWarnings = FALSE) + on.exit(unlink(save_path, recursive = TRUE)) + + ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = TRUE, resume = FALSE, + save_path = save_path) + + # verify the setup saved what we expect before testing the warning + expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) + expect_null(readRDS(file.path(save_path, "tcrossprod_ids.rds"))) + unlink(file.path(save_path, "final_matrix.rds")) # ensure we're testing the checkpoint loading, not final matrix loading + + expect_warning( + ped2com(hazard, component = "additive", sparse = FALSE, + keep_ids = keep, saveable = FALSE, resume = TRUE, + save_path = save_path), + "keep_ids do not match" + ) +}) From 4b2b8ce60073f690ec275f0c2f3c0b899323afb4 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 22:39:20 -0400 Subject: [PATCH 14/32] yamls --- .github/workflows/codecov.yaml => codecov.yaml | 0 codecov.yml | 17 +++++++++++++++++ 2 files changed, 17 insertions(+) rename .github/workflows/codecov.yaml => codecov.yaml (100%) create mode 100644 codecov.yml diff --git a/.github/workflows/codecov.yaml b/codecov.yaml similarity index 100% rename from .github/workflows/codecov.yaml rename to codecov.yaml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..6c208bba --- /dev/null +++ b/codecov.yml @@ -0,0 +1,17 @@ +comment: true + +coverage: + precision: 1 + round: down + range: "70...100" + status: + patch: + default: + target: auto + threshold: 10% + informational: true + project: + default: + target: auto + threshold: 1% + informational: false From aaf973f450f5630881eac72d9b5e6e38118a2b6d Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Tue, 24 Mar 2026 22:42:52 -0400 Subject: [PATCH 15/32] clean up --- .Rbuildignore | 40 +++++++++------ .github/workflows/check_on_branch.yml | 20 ++++++++ .github/workflows/check_on_different_r_os.yml | 51 +++++++++++++++++++ .github/workflows/check_on_main.yml | 19 +++++++ .github/workflows/release.yml | 30 +++++++++++ .gitignore | 42 ++++++++++++--- DESCRIPTION | 24 +++++---- 7 files changed, 194 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/check_on_branch.yml create mode 100644 .github/workflows/check_on_different_r_os.yml create mode 100644 .github/workflows/check_on_main.yml create mode 100644 .github/workflows/release.yml diff --git a/.Rbuildignore b/.Rbuildignore index e3e8da59..c5aa8e6d 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,26 +1,36 @@ +CITATION.cff$ +^.*\.Rproj$ ^BGmisc\.Rproj$ -^\.Rproj\.user$ +^BGmisc\.code-workspace$ +^BGmisc_main\.code-workspace$ +^CITATION\.cff$ +^CODE_OF_CONDUCT\.md$ +^CONTRIBUTING\.md$ +^CRAN-SUBMISSION$ +^LICENSE.md$ ^LICENSE\.md$ +^Meta$ ^R/\.Rhistory$ ^R/paper$ -^checkParents\.X -^test-clean\.X -CITATION.cff$ -^doc$ -^data-raw$ -^Meta$ -^vignettes/articles$ ^README\.Rmd$ +^\.Rproj\.user$ ^\.github$ -^cran-comments\.md$ -^CRAN-SUBMISSION$ -^BGmisc\.code-workspace$ +^\.httr-oauth$ ^\.lintr$ -^CODE_OF_CONDUCT\.md$ -^CONTRIBUTING\.md$ +^\.vscode$ +^\.zenodo\.json$ +^_pkgdown.yml$ ^_pkgdown\.yml$ +^checkParents\.X +^checklist.yml$ +^codecov\.yml$ +^cran-comments\.md$ +^data-raw$ +^doc$ ^docs$ +^man-roxygen$ +^organisation.yml$ ^pkgdown$ -^\.vscode$ -^BGmisc_main\.code-workspace$ ^revdep$ +^test-clean\.X +^vignettes/articles$ diff --git a/.github/workflows/check_on_branch.yml b/.github/workflows/check_on_branch.yml new file mode 100644 index 00000000..bc635a07 --- /dev/null +++ b/.github/workflows/check_on_branch.yml @@ -0,0 +1,20 @@ +on: + push: + branches-ignore: + - main + - master + - ghpages + +name: "check package with checklist" + +jobs: + check-package: + runs-on: ubuntu-latest + name: "check package" + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: read + steps: + - uses: inbo/actions/check_pkg@main diff --git a/.github/workflows/check_on_different_r_os.yml b/.github/workflows/check_on_different_r_os.yml new file mode 100644 index 00000000..2e692b64 --- /dev/null +++ b/.github/workflows/check_on_different_r_os.yml @@ -0,0 +1,51 @@ +on: + push: + branches: + - main + - master + pull_request: + branches: + - main + - master + +name: R-CMD-check-OS + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: macOS-latest, r: 'release'} + - {os: windows-latest, r: 'release'} + - {os: ubuntu-24.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/noble/latest"} + - {os: ubuntu-24.04, r: 'oldrel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/noble/latest"} + + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + _R_CHECK_SYSTEM_CLOCK_: false + RSPM: ${{ matrix.config.rspm }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v3 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + extra-repositories: https://inbo.r-universe.dev + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::rcmdcheck + needs: check + + - uses: r-lib/actions/check-r-package@v2 + with: + error-on: '"error"' diff --git a/.github/workflows/check_on_main.yml b/.github/workflows/check_on_main.yml new file mode 100644 index 00000000..6e8268dc --- /dev/null +++ b/.github/workflows/check_on_main.yml @@ -0,0 +1,19 @@ +on: + push: + branches: + - main + - master +permissions: + contents: write + +name: "check package on main with checklist" + +jobs: + check-package: + runs-on: ubuntu-latest + name: "check package" + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: inbo/actions/check_pkg@main diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..9b10b9f6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Releases + +on: + push: + tags: + - v* + workflow_run: + workflows: ["check package on main with checklist"] + types: + - completed + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + - name: Get tag + run: | + git fetch --tags --force + TAG=$(git tag --contains $(git rev-parse HEAD)) + TAG_BODY=$(git tag --contains $(git rev-parse HEAD) --format='%(contents)') + echo "tag=$TAG" >> $GITHUB_ENV + echo "$TAG_BODY" > body.md + - uses: ncipollo/release-action@v1 + with: + name: Release ${{ env.tag }} + tag: ${{ env.tag }} + bodyFile: body.md diff --git a/.gitignore b/.gitignore index 4a53a3da..3b74a301 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,56 @@ +!source/**/_extensions/** *.ASOIAF.ged *.Rproj +*.[rR][dD]ata +*.[rR]ds +*.dbf +*.doc* +*.eps +*.gddoc +*.gdsheet +*.gpkg +*.html *.knit.md +*.mdb +*.pdf +*.shp* +*.shx +*.sty +*.tex +*.xls* +*_cache +*_files +*_freeze +*_libs .DS_Store +.RData .Rdata +.Renviron .Rhistory .Rproj.user +.Ruserdata .httr-oauth .quarto .vscode/launch.json +.vscode/settings.json +/.claude /Meta/ BGmisc.code-workspace R/.Rhistory benchmark_results.csv +data-raw/Landers-Wilson-Garrison Tree.ged +data-raw/logo_orange.png dataRelatedPairs.csv dataRelatedPairs_new2.csv +docs +libs +output paper/paper.html +renv/library +revdep/ tests/testthat/Rplots.pdf vignettes/articles/paper.html -.vscode/settings.json -data-raw/logo_orange.png -data-raw/Landers-Wilson-Garrison Tree.ged -vignettes/understanding_relatedness.Rmd vignettes/rewritten_relatedness_vignette.Rmd -vignettes/understanding_relatedness.Xmd vignettes/rewritten_relatedness_vignette.Xmd -revdep/ -/.claude +vignettes/understanding_relatedness.Rmd +vignettes/understanding_relatedness.Xmd diff --git a/DESCRIPTION b/DESCRIPTION index 747cd677..7477defd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -14,13 +14,17 @@ Authors@R: c( person(c("S.", "Alexandra"), "Burt", role = "aut", comment = c(ORCID = "0000-0001-5538-7431")) ) -Description: Provides functions for behavior genetics analysis, - including variance component model identification [Hunter et al. (2021) ], - calculation of relatedness coefficients using path-tracing methods - [Wright (1922) ; McArdle & McDonald (1984) ], - inference of relatedness, pedigree conversion, and simulation of multi-generational family data - [Lyu et al. (2025) ]. For a full overview, - see [Garrison et al. (2024) ]. For a big data application see [Burt et al. (2025) . +Description: Provides functions for behavior genetics analysis, including + variance component model identification [Hunter et al. (2021) + ], calculation of relatedness + coefficients using path-tracing methods [Wright (1922) + ; McArdle & McDonald (1984) + ], inference of relatedness, + pedigree conversion, and simulation of multi-generational family data + [Lyu et al. (2025) ]. For a full + overview, see [Garrison et al. (2024) ]. For + a big data application see [Burt et al. (2025) . License: GPL-3 URL: https://github.com/R-Computing-Lab/BGmisc/, https://r-computing-lab.github.io/BGmisc/ @@ -31,9 +35,9 @@ Imports: data.table, igraph, Matrix, + methods, stats, - stringr, - methods + stringr Suggests: corrplot, discord, @@ -43,11 +47,11 @@ Suggests: ggplot2, kinship2, knitr, + mvtnorm, OpenMx, rmarkdown, testthat (>= 3.0.0), tidyverse, - mvtnorm, withr VignetteBuilder: knitr From 0f6d3183d689c6e97b05d537ded18244d36e235e Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 09:39:04 -0400 Subject: [PATCH 16/32] Update _pkgdown.yml --- _pkgdown.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index 3ee3892d..cc6460d3 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,4 +1,4 @@ -url: https://r-computing-lab.github.io/BGmisc/ template: bootstrap: 5 - + light-switch: false +url: https://R-Computing-Lab.github.io/BGmisc From 8fab0c84253e6707bbebb451b879fd758365755c Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 15:33:34 -0400 Subject: [PATCH 17/32] Update test-buildComponent.R --- tests/testthat/test-buildComponent.R | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 4b26e14f..9a265f39 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -377,6 +377,36 @@ test_that("keep_ids subset produces correct relatedness values", { }) +test_that("keep_ids subset produces correct relatedness values ", { + data(inbreeding) + keep <- as.character(sample(inbreeding$ID, 6)) + + r_full <- ped2com(inbreeding, component = "additive", sparse = FALSE, + keep_ids = NULL) + r_sub <- ped2com(inbreeding, component = "additive", sparse = FALSE, + keep_ids = keep) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + + + r_full <- ped2com(inbreeding, component = "additive", sparse = T, + keep_ids = NULL) + r_sub <- ped2com(inbreeding, component = "additive", sparse = T, + keep_ids = keep) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + +}) + + test_that("keep_ids with unknown IDs warns and drops missing entries", { data(hazard) keep <- c(as.character(hazard$ID[1:3]), "BOGUS_ID") From bca15c5fca6c4fa8435a7d4e16b8d62a1c6438d1 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 15:46:59 -0400 Subject: [PATCH 18/32] fixed chunks --- NEWS.md | 2 +- man/dot-computeTranspose.Rd | 2 +- man/ped2add.Rd | 2 +- man/ped2com.Rd | 2 +- tests/testthat/test-buildComponent.R | 5 +++-- tests/testthat/test-buildComponent_chunks.R | 6 +++--- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0ed00222..e3ddd514 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,7 @@ # BGmisc NEWS # Development version: -* Fixed bug in parList +* Fixed bug in parList * Moved wrappers of ped2com to own .R file * Fixed missing checkpoint for ram_checkpoint * Try a chunk_size argument for ped2com to reduce memory usage during transpose diff --git a/man/dot-computeTranspose.Rd b/man/dot-computeTranspose.Rd index e0d7b040..147b0c1b 100644 --- a/man/dot-computeTranspose.Rd +++ b/man/dot-computeTranspose.Rd @@ -19,7 +19,7 @@ \item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} -\item{chunk_size}{integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000.} +\item{chunk_size}{numeric. If greater than 1 is Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000. If less than or equal to 1, the entire matrix is processed in a single chunk.} \item{verbose}{logical. If TRUE, print progress through stages of algorithm} diff --git a/man/ped2add.Rd b/man/ped2add.Rd index e0e875cd..d4853de5 100644 --- a/man/ped2add.Rd +++ b/man/ped2add.Rd @@ -46,7 +46,7 @@ ped2add( \item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} -\item{chunk_size}{integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000.} +\item{chunk_size}{numeric. If greater than 1 is Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000. If less than or equal to 1, the entire matrix is processed in a single chunk.} \item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} diff --git a/man/ped2com.Rd b/man/ped2com.Rd index 2795e5dd..8ea24178 100644 --- a/man/ped2com.Rd +++ b/man/ped2com.Rd @@ -53,7 +53,7 @@ ped2com( \item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} -\item{chunk_size}{integer. Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000.} +\item{chunk_size}{numeric. If greater than 1 is Number of rows per chunk when \code{transpose_method = "chunked"}. Defaults to 1000. If less than or equal to 1, the entire matrix is processed in a single chunk.} \item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 9a265f39..141a763f 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -379,7 +379,8 @@ test_that("keep_ids subset produces correct relatedness values", { test_that("keep_ids subset produces correct relatedness values ", { data(inbreeding) - keep <- as.character(sample(inbreeding$ID, 6)) + for (i in unique(inbreeding$famID)) { + keep <- as.character(sample(inbreeding$ID[inbreeding$famID ==i], 6)) r_full <- ped2com(inbreeding, component = "additive", sparse = FALSE, keep_ids = NULL) @@ -403,7 +404,7 @@ test_that("keep_ids subset produces correct relatedness values ", { # values in the subset must match the corresponding entries of the full matrix expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) - +} }) diff --git a/tests/testthat/test-buildComponent_chunks.R b/tests/testthat/test-buildComponent_chunks.R index fdb08bb8..245da157 100644 --- a/tests/testthat/test-buildComponent_chunks.R +++ b/tests/testthat/test-buildComponent_chunks.R @@ -108,16 +108,16 @@ test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and siz test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and size is propoportion", { data(hazard) save_path <- file.path(tempdir(), "test_chunk_save") - unlink(save_path, recursive = TRUE) + dir.create(save_path, showWarnings = FALSE) on.exit(unlink(save_path, recursive = TRUE)) - chunk_size <- .3 + chunk_size <- .32 r_full <- ped2com(hazard, component = "additive", sparse = FALSE, transpose_method = "chunked", chunk_size = chunk_size, saveable = TRUE, resume = FALSE, save_path = save_path) - n_chunks <- ceiling(nrow(r_full)*chunk_size) + n_chunks <- ceiling(nrow(r_full) / ceiling(nrow(r_full) * chunk_size)) for (i in seq_len(n_chunks)) { expect_true(file.exists(chunk_path(save_path, i)), info = paste("chunk file", i, "should exist")) From 4da01af8f992c3071071526460ec4731efe21986 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 15:55:31 -0400 Subject: [PATCH 19/32] smarter --- NEWS.md | 2 +- tests/testthat/test-buildComponent.R | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/NEWS.md b/NEWS.md index e3ddd514..aa6b581a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,7 +5,7 @@ * Moved wrappers of ped2com to own .R file * Fixed missing checkpoint for ram_checkpoint * Try a chunk_size argument for ped2com to reduce memory usage during transpose -* Try filter method for what relatednessed to return +* Try filter method for whose relatedness to return by individual ID # BGmisc 1.6.0.1 ## CRAN submission diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 141a763f..4bcb8e5c 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -377,25 +377,27 @@ test_that("keep_ids subset produces correct relatedness values", { }) -test_that("keep_ids subset produces correct relatedness values ", { +test_that("keep_ids subset produces correct relatedness values across all families", { data(inbreeding) + + r_full_nosparse <- ped2com(inbreeding, component = "additive", sparse = FALSE, + keep_ids = NULL) + + r_full_sparse <- ped2com(inbreeding, component = "additive", sparse = T, + keep_ids = NULL) for (i in unique(inbreeding$famID)) { keep <- as.character(sample(inbreeding$ID[inbreeding$famID ==i], 6)) - r_full <- ped2com(inbreeding, component = "additive", sparse = FALSE, - keep_ids = NULL) r_sub <- ped2com(inbreeding, component = "additive", sparse = FALSE, keep_ids = keep) expect_equal(dim(r_sub), c(length(keep), length(keep))) expect_equal(rownames(r_sub), keep) - + r_full <- r_full_nosparse # values in the subset must match the corresponding entries of the full matrix expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) - - r_full <- ped2com(inbreeding, component = "additive", sparse = T, - keep_ids = NULL) + r_full <- r_full_sparse r_sub <- ped2com(inbreeding, component = "additive", sparse = T, keep_ids = keep) From b0b54571c4c7b6b9d66714de8ce9dcdaf5467e71 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 17:16:48 -0400 Subject: [PATCH 20/32] Update buildComponent.R --- DESCRIPTION | 2 +- R/buildComponent.R | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 7477defd..28c8b283 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: BGmisc Title: An R Package for Extended Behavior Genetics Analysis -Version: 1.6.0.1 +Version: 1.6.0.9 Authors@R: c( person("S. Mason", "Garrison", , "garrissm@wfu.edu", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-4804-6003")), diff --git a/R/buildComponent.R b/R/buildComponent.R index aece5547..e5ebc092 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -364,7 +364,7 @@ ped2com <- function(ped, component, missing <- config$keep_ids[is.na(idx)] if (length(missing) > 0) { warning(length(missing), " keep_ids not found in pedigree and will be dropped: ", - paste(head(missing, 5), collapse = ", "), + paste(Matrix::head(missing, 5), collapse = ", "), if (length(missing) > 5) " ..." else "") } idx <- idx[!is.na(idx)] @@ -581,7 +581,7 @@ ped2com <- function(ped, component, if(force_symmetric == TRUE) { - Matrix:::forceSymmetric( do.call(rbind, blocks)) + Matrix::forceSymmetric( do.call(rbind, blocks)) } else { do.call(rbind, blocks) } From 94cabd35b30a7332959091e517214999d5c93cda Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 17:36:40 -0400 Subject: [PATCH 21/32] docs --- R/buildComponent.R | 3 ++- R/buildComponentWrappers.R | 1 + man/dot-computeTranspose.Rd | 4 ++++ man/ped2ce.Rd | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index e5ebc092..86c31e33 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -496,7 +496,8 @@ ped2com <- function(ped, component, #' @inherit ped2com details #' @param r2 a relatedness matrix #' @param force_symmetric logical. If TRUE, forces the output matrix to be symmetric using Matrix::forceSymmetric. This can be helpful when using chunked multiplication to ensure the final result is exactly symmetric despite potential numerical issues. Defaults to TRUE. -#' +#' @param checkpoint_files list of checkpoint file paths for saving intermediate results when using chunked multiplication. Should contain at least 'tcrossprod_checkpoint' for saving the chunks and 'tcrossprod_ids' for saving the keep_ids used in the tcrossprod checkpoint. +#' @param config list of configuration parameters, used for checkpointing and verbose output .computeTranspose <- function(r2, transpose_method = "tcrossprod", chunk_size = 1000L, verbose = FALSE, force_symmetric = FALSE, config = NULL, checkpoint_files = NULL diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R index ee510fdc..87683a6e 100644 --- a/R/buildComponentWrappers.R +++ b/R/buildComponentWrappers.R @@ -177,6 +177,7 @@ ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, #' Take a pedigree and turn it into an extended environmental relatedness matrix #' @inheritParams ped2com #' @inherit ped2com details +#' @param personID Character. Column name for individual IDs. #' @export #' ped2ce <- function(ped, personID = "ID", diff --git a/man/dot-computeTranspose.Rd b/man/dot-computeTranspose.Rd index 147b0c1b..ae54d2ab 100644 --- a/man/dot-computeTranspose.Rd +++ b/man/dot-computeTranspose.Rd @@ -24,6 +24,10 @@ \item{verbose}{logical. If TRUE, print progress through stages of algorithm} \item{force_symmetric}{logical. If TRUE, forces the output matrix to be symmetric using Matrix::forceSymmetric. This can be helpful when using chunked multiplication to ensure the final result is exactly symmetric despite potential numerical issues. Defaults to TRUE.} + +\item{config}{list of configuration parameters, used for checkpointing and verbose output} + +\item{checkpoint_files}{list of checkpoint file paths for saving intermediate results when using chunked multiplication. Should contain at least 'tcrossprod_checkpoint' for saving the chunks and 'tcrossprod_ids' for saving the keep_ids used in the tcrossprod checkpoint.} } \description{ Compute the transpose multiplication for the relatedness matrix diff --git a/man/ped2ce.Rd b/man/ped2ce.Rd index 514841b3..e00489cc 100644 --- a/man/ped2ce.Rd +++ b/man/ped2ce.Rd @@ -9,6 +9,8 @@ ped2ce(ped, personID = "ID", ...) \arguments{ \item{ped}{a pedigree dataset. Needs ID, momID, and dadID columns} +\item{personID}{Character. Column name for individual IDs.} + \item{...}{additional arguments to be passed to \code{\link{ped2com}}} } \description{ From a272140f429ab6ffd21e0ddd87b428be50c8d5a9 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 17:55:48 -0400 Subject: [PATCH 22/32] Update DESCRIPTION Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 28c8b283..60d6f137 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,7 @@ Description: Provides functions for behavior genetics analysis, including [Lyu et al. (2025) ]. For a full overview, see [Garrison et al. (2024) ]. For a big data application see [Burt et al. (2025) . + 10.1016/j.ebiom.2025.105911>]. License: GPL-3 URL: https://github.com/R-Computing-Lab/BGmisc/, https://r-computing-lab.github.io/BGmisc/ From d596f0feed4fa49347e266fec8d33f3d51396eb8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 21:59:05 +0000 Subject: [PATCH 23/32] Fix non-ASCII character in buildComponent.R: replace em dash with \u2014 escape Co-authored-by: smasongarrison <6001608+smasongarrison@users.noreply.github.com> Agent-Logs-Url: https://github.com/R-Computing-Lab/BGmisc/sessions/1f51ade1-dbed-4745-9e6b-e3b18880f36c --- R/buildComponent.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 86c31e33..290d8a6f 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -392,7 +392,7 @@ ped2com <- function(ped, component, } else { use_tcrossprod_checkpoint <- FALSE warning( - "tcrossprod checkpoint keep_ids do not match — recomputing.\n", + "tcrossprod checkpoint keep_ids do not match \u2014 recomputing.\n", " saved: ", if (is.null(saved_keep_ids)) "NULL (full pedigree)" else paste(length(saved_keep_ids), "IDs"), "\n", " expected: ", if (is.null(config$keep_ids)) "NULL (full pedigree)" else paste(length(config$keep_ids), "IDs") ) From 3a2b8e27ff743f2ee3192d7cc349ae2ad04a26d5 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 17:59:14 -0400 Subject: [PATCH 24/32] tests --- .github/workflows/{check_on_branch.yml => check_on_branch.xml} | 0 .../{check_on_different_r_os.yml => check_on_different_r_os.xml} | 0 .github/workflows/{check_on_main.yml => check_on_main.xml} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{check_on_branch.yml => check_on_branch.xml} (100%) rename .github/workflows/{check_on_different_r_os.yml => check_on_different_r_os.xml} (100%) rename .github/workflows/{check_on_main.yml => check_on_main.xml} (100%) diff --git a/.github/workflows/check_on_branch.yml b/.github/workflows/check_on_branch.xml similarity index 100% rename from .github/workflows/check_on_branch.yml rename to .github/workflows/check_on_branch.xml diff --git a/.github/workflows/check_on_different_r_os.yml b/.github/workflows/check_on_different_r_os.xml similarity index 100% rename from .github/workflows/check_on_different_r_os.yml rename to .github/workflows/check_on_different_r_os.xml diff --git a/.github/workflows/check_on_main.yml b/.github/workflows/check_on_main.xml similarity index 100% rename from .github/workflows/check_on_main.yml rename to .github/workflows/check_on_main.xml From 607f609e2e2de28adc7cd3dff286abe89dbcc679 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 20:47:01 -0400 Subject: [PATCH 25/32] Apply suggestions from code review Update tests/testthat/test-buildComponent_chunks.R Update tests/testthat/test-buildComponent_chunks.R Co-Authored-By: Copilot <175728472+Copilot@users.noreply.github.com> --- R/buildComponent.R | 2 +- tests/testthat/test-buildComponent_chunks.R | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 290d8a6f..802c9cf5 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -21,7 +21,7 @@ #' @param isChild_method character. The method to use for computing the isChild matrix. Options are "classic" or "partialparent" #' @param adjBeta_method numeric The method to use for computing the building the adjacency_method matrix when using the "beta" build #' @param compress logical. If TRUE, use compression when saving the checkpoint files. Defaults to TRUE. -#' @param mz_twins logical. If TRUE, merge MZ co-twin columns in the r2 matrix before tcrossprod so that MZ twins are coded with relatedness 1 instead of 0.5. Twin pairs are identified from the \code{twinID} column. When a \code{zygosity} column is also present, only pairs where both members have \code{zygosity == "MZ"} are used; otherwise all \code{twinID} pairs are assumed to be MZ. Defaults to FALSE. +#' @param mz_twins logical. If TRUE, merge MZ co-twin columns in the r2 matrix before tcrossprod so that MZ twins are coded with relatedness 1 instead of 0.5. Twin pairs are identified from the \code{twinID} column. When a \code{zygosity} column is also present, only pairs where both members have \code{zygosity == "MZ"} are used; otherwise all \code{twinID} pairs are assumed to be MZ. Defaults to TRUE. #' @param mz_method character. The method to handle MZ twins. Options are "merging" (default) or "addtwins". "addtwins" adds the twin2 column to the twin1 column before tcrossprod so that all relatedness flows through a single source, then leaves the twin2 column as zero and relies on the fact that the row/col names are the same to copy the values back to twin2 after tcrossprod. "merging" merges the twin2 column into the twin1 column before tcrossprod and then copies the values back to twin2 after tcrossprod so that both twins appear in the final matrix. #' @param force_symmetric logical. If TRUE, force the final relatedness matrix to be symmetric. This can help mitigate any numerical asymmetry introduced by the transpose method, especially when using sparse matrices. Defaults to TRUE. #' @param beta logical. Used for benchmarking diff --git a/tests/testthat/test-buildComponent_chunks.R b/tests/testthat/test-buildComponent_chunks.R index 245da157..f4172eda 100644 --- a/tests/testthat/test-buildComponent_chunks.R +++ b/tests/testthat/test-buildComponent_chunks.R @@ -40,7 +40,7 @@ test_that("chunked tcrossprod matches standard tcrossprod", { object.size(r_chunked) / 1e9, object.size(r_standard) / 1e9) - expect_equal(Matrix:::forceSymmetric(r_chunked), + expect_equal(Matrix::forceSymmetric(r_chunked), r_chunked_sym, tolerance = 1e-10) expect_equal(r_standard, r_chunked_sym @@ -105,7 +105,7 @@ test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and siz } }) -test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and size is propoportion", { +test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and size is proportion", { data(hazard) save_path <- file.path(tempdir(), "test_chunk_save") From 9ad9f7e1864a6253d44e038615c13f8de4e1701d Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Wed, 25 Mar 2026 23:56:30 -0400 Subject: [PATCH 26/32] whitespace --- R/buildComponent.R | 50 ++--- R/buildComponentWrappers.R | 2 - R/readGedcom.R | 4 +- R/simulatePedigree.R | 48 ++-- R/summarizePedigree.R | 2 +- data-raw/optimizing_transpose.R | 45 ++-- man/BGmisc-package.Rd | 2 +- man/ped2add.Rd | 2 +- man/ped2com.Rd | 2 +- tests/testthat/test-buildComponent.R | 137 +++++++----- tests/testthat/test-buildComponent_chunks.R | 234 ++++++++++++-------- vignettes/v6_pedigree_model_fitting.Rmd | 56 +++-- 12 files changed, 335 insertions(+), 249 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 802c9cf5..6fb8162f 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -161,7 +161,7 @@ ped2com <- function(ped, component, } if (config$mz_method %in% c("merging") && config$mz_twins == TRUE && !is.null(mz_row_pairs) && length(mz_row_pairs) > 0 && - config$component %in% c("additive")) { + config$component %in% c("additive")) { # replace all MZ twin IDs with the first twin's ID in each pair so they are merged for the path tracing and all subsequent steps. We will copy the values back to the second twin at the end. ped <- fuseTwins(ped = ped, mz_row_pairs = mz_row_pairs, mz_id_pairs = mz_id_pairs, config = config, beta = beta) if (config$verbose == TRUE) { @@ -250,7 +250,7 @@ ped2com <- function(ped, component, mtSum <- 0 count <- 0 } else if (config$resume == TRUE && file.exists(checkpoint_files$r_checkpoint) && - file.exists(checkpoint_files$gen_checkpoint) && + file.exists(checkpoint_files$gen_checkpoint) && file.exists(checkpoint_files$mtSum_checkpoint) && file.exists(checkpoint_files$newIsPar_checkpoint) && file.exists(checkpoint_files$count_checkpoint) @@ -363,9 +363,11 @@ ped2com <- function(ped, component, idx <- match(config$keep_ids, rownames(r2)) missing <- config$keep_ids[is.na(idx)] if (length(missing) > 0) { - warning(length(missing), " keep_ids not found in pedigree and will be dropped: ", - paste(Matrix::head(missing, 5), collapse = ", "), - if (length(missing) > 5) " ..." else "") + warning( + length(missing), " keep_ids not found in pedigree and will be dropped: ", + paste(Matrix::head(missing, 5), collapse = ", "), + if (length(missing) > 5) " ..." else "" + ) } idx <- idx[!is.na(idx)] if (config$verbose == TRUE) { @@ -376,12 +378,12 @@ ped2com <- function(ped, component, use_tcrossprod_checkpoint <- FALSE if (config$resume == TRUE && file.exists(checkpoint_files$tcrossprod_checkpoint) && - config$component != "generation") { + config$component != "generation") { saved_keep_ids <- if (file.exists(checkpoint_files$tcrossprod_ids)) { readRDS(checkpoint_files$tcrossprod_ids) } else { - saved_keep_ids <- NULL - if(config$verbose == TRUE) { + saved_keep_ids <- NULL + if (config$verbose == TRUE) { message("No saved keep_ids found for tcrossprod checkpoint. Expected at: ", checkpoint_files$tcrossprod_ids, "\n") } } @@ -499,9 +501,8 @@ ped2com <- function(ped, component, #' @param checkpoint_files list of checkpoint file paths for saving intermediate results when using chunked multiplication. Should contain at least 'tcrossprod_checkpoint' for saving the chunks and 'tcrossprod_ids' for saving the keep_ids used in the tcrossprod checkpoint. #' @param config list of configuration parameters, used for checkpointing and verbose output .computeTranspose <- function(r2, transpose_method = "tcrossprod", chunk_size = 1000L, - verbose = FALSE, force_symmetric = FALSE, config = NULL, - checkpoint_files = NULL - ) { + verbose = FALSE, force_symmetric = FALSE, config = NULL, + checkpoint_files = NULL) { valid_methods <- c( "tcrossprod", "crossprod", "star", "tcross.alt.crossprod", "tcross.alt.star", @@ -519,7 +520,7 @@ ped2com <- function(ped, component, "tcross.alt.star" = "star" ) - if(chunk_size>1){ + if (chunk_size > 1) { chunk_size_method <- "lines" } else if (chunk_size > 0 && chunk_size <= 1) { chunk_size_method <- "proportion" @@ -567,7 +568,7 @@ ped2com <- function(ped, component, cat(sprintf(" chunk %d/%d (rows %d-%d)\n", i, n_chunks, row_start, row_end)) } - if(config$resume == TRUE && file.exists(paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds"))) { + if (config$resume == TRUE && file.exists(paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds"))) { if (verbose == TRUE) cat(" Resuming: Loading chunk from checkpoint...\n") blocks[[i]] <- readRDS(paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds")) next @@ -575,14 +576,14 @@ ped2com <- function(ped, component, blocks[[i]] <- Matrix::tcrossprod(r2[row_start:row_end, , drop = FALSE], r2) gc() - if(config$saveable == TRUE) { + if (config$saveable == TRUE) { saveRDS(blocks[[i]], file = paste0(checkpoint_files$tcrossprod_checkpoint, "_chunk_", i, ".rds"), compress = config$compress) } } - if(force_symmetric == TRUE) { - Matrix::forceSymmetric( do.call(rbind, blocks)) + if (force_symmetric == TRUE) { + Matrix::forceSymmetric(do.call(rbind, blocks)) } else { do.call(rbind, blocks) } @@ -590,7 +591,6 @@ ped2com <- function(ped, component, ) result - } #' Initialize checkpoint files @@ -598,11 +598,11 @@ ped2com <- function(ped, component, #' @keywords internal initializeCheckpoint <- function(config = list( - verbose = FALSE, - saveable = FALSE, - resume = FALSE, - save_path = "checkpoint/" -)) { + verbose = FALSE, + saveable = FALSE, + resume = FALSE, + save_path = "checkpoint/" + )) { # Define checkpoint files # Ensure save path exists if (config$saveable == TRUE && !dir.exists(config$save_path)) { @@ -647,7 +647,7 @@ initializeCheckpoint <- function(config = list( if (component %in% c("generation", "additive")) { parVal <- .5 } else if (component %in% - c("common nuclear", "mitochondrial", "mtdna", "mitochondria")) { + c("common nuclear", "mitochondrial", "mtdna", "mitochondria")) { parVal <- 1 } else { stop("Don't know how to set parental value") @@ -778,7 +778,7 @@ loadOrComputeCheckpoint <- function(file, compute_fn, parList = NULL, lens = NULL, compress = TRUE) { if (config$resume == TRUE && - file.exists(checkpoint_files$parList) && + file.exists(checkpoint_files$parList) && file.exists(checkpoint_files$lens)) { if (config$verbose == TRUE) { message("Resuming: Loading parent-child adjacency data...\n") @@ -801,7 +801,7 @@ loadOrComputeCheckpoint <- function(file, compute_fn, } if (config$resume == TRUE && - file.exists(checkpoint_files$iss) && + file.exists(checkpoint_files$iss) && file.exists(checkpoint_files$jss)) { # fix to check actual if (config$verbose == TRUE) message("Resuming: Constructed matrix...\n") jss <- readRDS(checkpoint_files$jss) diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R index 87683a6e..d6cd7c4a 100644 --- a/R/buildComponentWrappers.R +++ b/R/buildComponentWrappers.R @@ -1,4 +1,3 @@ - #' Take a pedigree and turn it into an additive genetics relatedness matrix #' @inheritParams ped2com #' @inherit ped2com details @@ -184,4 +183,3 @@ ped2ce <- function(ped, personID = "ID", ...) { matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped[[personID]], ped[[personID]])) } - diff --git a/R/readGedcom.R b/R/readGedcom.R index 965b857e..5464f47c 100644 --- a/R/readGedcom.R +++ b/R/readGedcom.R @@ -484,8 +484,8 @@ process_tag <- function(tag, field_name, pattern_rows, line, vars, count_name <- paste0("num_", tolower(tag), "_rows") matched <- FALSE if (!is.null(pattern_rows[[count_name]]) && - pattern_rows[[count_name]] > 0 && - grepl(paste0(" ", tag), line)) { + pattern_rows[[count_name]] > 0 && + grepl(paste0(" ", tag), line)) { value <- if (is.null(extractor)) { extract_info(line, tag) } else { diff --git a/R/simulatePedigree.R b/R/simulatePedigree.R index eb4489f6..f3c170b6 100644 --- a/R/simulatePedigree.R +++ b/R/simulatePedigree.R @@ -23,10 +23,10 @@ #' buildBtwnGenerations <- function(df_Fam, Ngen, sizeGens, verbose = FALSE, marR, sexR, kpc, - rd_kpc, personID = "ID", - momID = "momID", - dadID = "dadID", - code_male = "M", code_female = "F", beta = FALSE) { + rd_kpc, personID = "ID", + momID = "momID", + dadID = "dadID", + code_male = "M", code_female = "F", beta = FALSE) { # Normalize string aliases to logical values for downstream functions use_optimized <- FALSE @@ -80,16 +80,16 @@ buildBtwnGenerations <- function(df_Fam, Ngen, sizeGens, verbose = FALSE, marR, buildBtwnGenerations_base <- function(df_Fam, - Ngen, - sizeGens, - verbose = FALSE, - marR, sexR, kpc, - rd_kpc, personID = "ID", - momID = "momID", - dadID = "dadID", - code_male = "M", - code_female = "F", - beta = FALSE) { + Ngen, + sizeGens, + verbose = FALSE, + marR, sexR, kpc, + rd_kpc, personID = "ID", + momID = "momID", + dadID = "dadID", + code_male = "M", + code_female = "F", + beta = FALSE) { # Initialize flags for the full pedigree data frame. # These are used throughout linkage and get overwritten per-generation as needed. @@ -454,16 +454,16 @@ buildBtwnGenerations_base <- function(df_Fam, } buildBtwnGenerations_opt <- function(df_Fam, - Ngen, - sizeGens, - verbose = FALSE, - marR, sexR, kpc, - rd_kpc, personID = "ID", - momID = "momID", - dadID = "dadID", - code_male = "M", - code_female = "F", - beta = TRUE) { + Ngen, + sizeGens, + verbose = FALSE, + marR, sexR, kpc, + rd_kpc, personID = "ID", + momID = "momID", + dadID = "dadID", + code_male = "M", + code_female = "F", + beta = TRUE) { # Initialize flags for the full pedigree data frame. # These are used throughout linkage and get overwritten per-generation as needed. diff --git a/R/summarizePedigree.R b/R/summarizePedigree.R index b77d9d92..4e1e1f94 100644 --- a/R/summarizePedigree.R +++ b/R/summarizePedigree.R @@ -78,7 +78,7 @@ summarizePedigrees <- function(ped, ) } if (!is.null(founder_sort_var) && - !founder_sort_var %in% names(ped)) { + !founder_sort_var %in% names(ped)) { stop( "If you set founder_sort_var, that variable must be a column in the pedigree data. If you want to sort by using the default, set founder_sort_var = NULL. The default is to sort by birth year if that's present and by personID otherwise." ) diff --git a/data-raw/optimizing_transpose.R b/data-raw/optimizing_transpose.R index a2aaacc3..587859df 100644 --- a/data-raw/optimizing_transpose.R +++ b/data-raw/optimizing_transpose.R @@ -54,8 +54,10 @@ levels <- list( # Conversion-side factors (ped2com) component = c("additive"), - transpose_method = c("tcrossprod", "crossprod", "star", - "chunked"), + transpose_method = c( + "tcrossprod", "crossprod", "star", + "chunked" + ), twin_method = c("NULL"), beta = c(TRUE), sparse_matrix = c(FALSE, TRUE) # user-facing name, translated to ped2com's `sparse` @@ -75,11 +77,11 @@ scopes <- list( # Each scenario says what to vary and what to fix. No other code changes. scenarios <- list( full = list( - vary = c("ped", "marR", "twin_method", "beta", "sparse_matrix","transpose_method"), + vary = c("ped", "marR", "twin_method", "beta", "sparse_matrix", "transpose_method"), fixed = list() ), quick = list( - vary = c("ped", "twin_method","transpose_method"), + vary = c("ped", "twin_method", "transpose_method"), fixed = list(marR = 0.8, beta = FALSE, sparse_matrix = TRUE, component = "additive") ) @@ -163,7 +165,7 @@ design <- design %>% # --------------------------- # 4) Simulation cache (simulate once per unique sim condition) # --------------------------- -simulate_one <- function(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta,fam_shift=1) { +simulate_one <- function(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta, fam_shift = 1) { simulatePedigree( kpc = kpc, Ngen = Ngen_total, sexR = sexR, marR = marR, fam_shift = fam_shift, @@ -172,14 +174,14 @@ simulate_one <- function(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta,fam_shi makeTwins(gen_twin = gen_twin) } -simulate_many <- function(number_of_families, - Ngen_total, gen_twin, kpc, sexR, marR, sim_beta) { - replicate(simulate_one(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta,fam_shift = 1 - ), number_of_families, simplify = FALSE) +simulate_many <- function( + number_of_families, + Ngen_total, gen_twin, kpc, sexR, marR, sim_beta +) { + replicate(simulate_one(Ngen_total, gen_twin, kpc, sexR, marR, sim_beta, fam_shift = 1), number_of_families, simplify = FALSE) } - sim_tbl <- design %>% distinct(across(all_of(scopes$sim))) %>% mutate( @@ -288,8 +290,10 @@ results <- results %>% ) ), ped_label = factor(ped_label, levels = levels$ped$ped_label), - gen_factor = factor(ped_label, levels = levels$ped$ped_label, - labels = paste0(levels$ped$Ngen_total, " gen")) + gen_factor = factor(ped_label, + levels = levels$ped$ped_label, + labels = paste0(levels$ped$Ngen_total, " gen") + ) ) write_csv(results, "data-raw/ped2com_benchmark_results.csv") @@ -348,7 +352,7 @@ results %>% linewidth = 0.25 ) + scale_y_log10() + - # facet_grid(~scenario) + + # facet_grid(~scenario) + labs( title = "Benchmarking ped2com() by transpose method", x = "Pedigree", @@ -357,15 +361,14 @@ results %>% fill = "Transpose method" ) + theme_minimal() + -# scale_fill_manual(values = c( -# "beta=FALSE, sparse=FALSE" = "lightgray", -# "beta=FALSE, sparse=TRUE" = "gray8", -# "beta=TRUE, sparse=FALSE" = "lightcoral", -# "beta=TRUE, sparse=TRUE" = "red2" -# )) + + # scale_fill_manual(values = c( + # "beta=FALSE, sparse=FALSE" = "lightgray", + # "beta=FALSE, sparse=TRUE" = "gray8", + # "beta=TRUE, sparse=FALSE" = "lightcoral", + # "beta=TRUE, sparse=TRUE" = "red2" + # )) + scale_color_manual(values = c("FALSE" = "gray", "TRUE" = "black")) - #c("NULL" = "gray", "addtwins" = "skyblue3", "merging" = "tomato2")) +# c("NULL" = "gray", "addtwins" = "skyblue3", "merging" = "tomato2")) # df <- sim_tbl$ped[[2]] # df_add <- df %>% ped2add() - diff --git a/man/BGmisc-package.Rd b/man/BGmisc-package.Rd index 7699a01c..4b2b17c4 100644 --- a/man/BGmisc-package.Rd +++ b/man/BGmisc-package.Rd @@ -6,7 +6,7 @@ \alias{BGmisc-package} \title{BGmisc: An R Package for Extended Behavior Genetics Analysis} \description{ -Provides functions for behavior genetics analysis, including variance component model identification [Hunter et al. (2021) \doi{10.1007/s10519-021-10055-x}], calculation of relatedness coefficients using path-tracing methods [Wright (1922) \doi{10.1086/279872}; McArdle & McDonald (1984) \doi{10.1111/j.2044-8317.1984.tb00802.x}], inference of relatedness, pedigree conversion, and simulation of multi-generational family data [Lyu et al. (2025) \doi{10.1007/s10519-025-10225-1}]. For a full overview, see [Garrison et al. (2024) \doi{10.21105/joss.06203}]. For a big data application see [Burt et al. (2025) \doi{ 10.1016/j.ebiom.2025.105911}. +Provides functions for behavior genetics analysis, including variance component model identification [Hunter et al. (2021) \doi{10.1007/s10519-021-10055-x}], calculation of relatedness coefficients using path-tracing methods [Wright (1922) \doi{10.1086/279872}; McArdle & McDonald (1984) \doi{10.1111/j.2044-8317.1984.tb00802.x}], inference of relatedness, pedigree conversion, and simulation of multi-generational family data [Lyu et al. (2025) \doi{10.1007/s10519-025-10225-1}]. For a full overview, see [Garrison et al. (2024) \doi{10.21105/joss.06203}]. For a big data application see [Burt et al. (2025) \doi{ 10.1016/j.ebiom.2025.105911}]. } \seealso{ Useful links: diff --git a/man/ped2add.Rd b/man/ped2add.Rd index d4853de5..78494229 100644 --- a/man/ped2add.Rd +++ b/man/ped2add.Rd @@ -66,7 +66,7 @@ ped2add( \item{compress}{logical. If TRUE, use compression when saving the checkpoint files. Defaults to TRUE.} -\item{mz_twins}{logical. If TRUE, merge MZ co-twin columns in the r2 matrix before tcrossprod so that MZ twins are coded with relatedness 1 instead of 0.5. Twin pairs are identified from the \code{twinID} column. When a \code{zygosity} column is also present, only pairs where both members have \code{zygosity == "MZ"} are used; otherwise all \code{twinID} pairs are assumed to be MZ. Defaults to FALSE.} +\item{mz_twins}{logical. If TRUE, merge MZ co-twin columns in the r2 matrix before tcrossprod so that MZ twins are coded with relatedness 1 instead of 0.5. Twin pairs are identified from the \code{twinID} column. When a \code{zygosity} column is also present, only pairs where both members have \code{zygosity == "MZ"} are used; otherwise all \code{twinID} pairs are assumed to be MZ. Defaults to TRUE.} \item{mz_method}{character. The method to handle MZ twins. Options are "merging" (default) or "addtwins". "addtwins" adds the twin2 column to the twin1 column before tcrossprod so that all relatedness flows through a single source, then leaves the twin2 column as zero and relies on the fact that the row/col names are the same to copy the values back to twin2 after tcrossprod. "merging" merges the twin2 column into the twin1 column before tcrossprod and then copies the values back to twin2 after tcrossprod so that both twins appear in the final matrix.} diff --git a/man/ped2com.Rd b/man/ped2com.Rd index 8ea24178..900a1e7b 100644 --- a/man/ped2com.Rd +++ b/man/ped2com.Rd @@ -79,7 +79,7 @@ ped2com( \item{compress}{logical. If TRUE, use compression when saving the checkpoint files. Defaults to TRUE.} -\item{mz_twins}{logical. If TRUE, merge MZ co-twin columns in the r2 matrix before tcrossprod so that MZ twins are coded with relatedness 1 instead of 0.5. Twin pairs are identified from the \code{twinID} column. When a \code{zygosity} column is also present, only pairs where both members have \code{zygosity == "MZ"} are used; otherwise all \code{twinID} pairs are assumed to be MZ. Defaults to FALSE.} +\item{mz_twins}{logical. If TRUE, merge MZ co-twin columns in the r2 matrix before tcrossprod so that MZ twins are coded with relatedness 1 instead of 0.5. Twin pairs are identified from the \code{twinID} column. When a \code{zygosity} column is also present, only pairs where both members have \code{zygosity == "MZ"} are used; otherwise all \code{twinID} pairs are assumed to be MZ. Defaults to TRUE.} \item{mz_method}{character. The method to handle MZ twins. Options are "merging" (default) or "addtwins". "addtwins" adds the twin2 column to the twin1 column before tcrossprod so that all relatedness flows through a single source, then leaves the twin2 column as zero and relies on the fact that the row/col names are the same to copy the values back to twin2 after tcrossprod. "merging" merges the twin2 column into the twin1 column before tcrossprod and then copies the values back to twin2 after tcrossprod so that both twins appear in the final matrix.} diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 4bcb8e5c..d3030895 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -305,23 +305,29 @@ test_that("resume loads ram_checkpoint and skips RAM loop when mid-loop files ab on.exit(unlink(save_path, recursive = TRUE)) # First run: save all checkpoints - r_full <- ped2com(hazard, component = "additive", sparse = FALSE, - saveable = TRUE, resume = FALSE, - save_rate_gen = 1, save_path = save_path) + r_full <- ped2com(hazard, + component = "additive", sparse = FALSE, + saveable = TRUE, resume = FALSE, + save_rate_gen = 1, save_path = save_path + ) # Remove mid-loop files so only ram_checkpoint (and earlier) remain - mid_loop_files <- c("r_checkpoint.rds", "gen_checkpoint.rds", - "mtSum_checkpoint.rds", "newIsPar_checkpoint.rds", - "count_checkpoint.rds") + mid_loop_files <- c( + "r_checkpoint.rds", "gen_checkpoint.rds", + "mtSum_checkpoint.rds", "newIsPar_checkpoint.rds", + "count_checkpoint.rds" + ) file.remove(file.path(save_path, mid_loop_files)) expect_true(file.exists(file.path(save_path, "ram_checkpoint.rds"))) expect_false(file.exists(file.path(save_path, "r_checkpoint.rds"))) # Second run: should load ram_checkpoint, skip loop, and produce same result - r_resumed <- ped2com(hazard, component = "additive", sparse = FALSE, - saveable = FALSE, resume = TRUE, - save_path = save_path) + r_resumed <- ped2com(hazard, + component = "additive", sparse = FALSE, + saveable = FALSE, resume = TRUE, + save_path = save_path + ) expect_equal(r_full, r_resumed) }) @@ -332,16 +338,20 @@ test_that("ram_checkpoint resume produces identical result to fresh run", { dir.create(save_path, showWarnings = FALSE) on.exit(unlink(save_path, recursive = TRUE)) - r_fresh <- ped2com(hazard, component = "additive", sparse = FALSE, - saveable = TRUE, resume = FALSE, - save_rate_gen = 1, save_path = save_path) + r_fresh <- ped2com(hazard, + component = "additive", sparse = FALSE, + saveable = TRUE, resume = FALSE, + save_rate_gen = 1, save_path = save_path + ) file.remove(file.path(save_path, "r_checkpoint.rds")) file.remove(file.path(save_path, "tcrossprod_checkpoint.rds")) - r_resumed <- ped2com(hazard, component = "additive", sparse = FALSE, - saveable = FALSE, resume = TRUE, - save_path = save_path) + r_resumed <- ped2com(hazard, + component = "additive", sparse = FALSE, + saveable = FALSE, resume = TRUE, + save_path = save_path + ) expect_equal(r_fresh, r_resumed, tolerance = 1e-10) }) @@ -352,10 +362,14 @@ test_that("keep_ids subset produces correct relatedness values", { data(hazard) keep <- as.character(hazard$ID[5:10]) - r_full <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL) - r_sub <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep) + r_full <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = NULL + ) + r_sub <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = keep + ) expect_equal(dim(r_sub), c(length(keep), length(keep))) expect_equal(rownames(r_sub), keep) @@ -364,49 +378,60 @@ test_that("keep_ids subset produces correct relatedness values", { expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) - r_full <- ped2com(hazard, component = "additive", sparse = T, - keep_ids = NULL) - r_sub <- ped2com(hazard, component = "additive", sparse = T, - keep_ids = keep) + r_full <- ped2com(hazard, + component = "additive", sparse = T, + keep_ids = NULL + ) + r_sub <- ped2com(hazard, + component = "additive", sparse = T, + keep_ids = keep + ) expect_equal(dim(r_sub), c(length(keep), length(keep))) expect_equal(rownames(r_sub), keep) # values in the subset must match the corresponding entries of the full matrix expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) - }) test_that("keep_ids subset produces correct relatedness values across all families", { data(inbreeding) - r_full_nosparse <- ped2com(inbreeding, component = "additive", sparse = FALSE, - keep_ids = NULL) + r_full_nosparse <- ped2com(inbreeding, + component = "additive", sparse = FALSE, + keep_ids = NULL + ) - r_full_sparse <- ped2com(inbreeding, component = "additive", sparse = T, - keep_ids = NULL) + r_full_sparse <- ped2com(inbreeding, + component = "additive", sparse = T, + keep_ids = NULL + ) for (i in unique(inbreeding$famID)) { - keep <- as.character(sample(inbreeding$ID[inbreeding$famID ==i], 6)) - - r_sub <- ped2com(inbreeding, component = "additive", sparse = FALSE, - keep_ids = keep) - - expect_equal(dim(r_sub), c(length(keep), length(keep))) - expect_equal(rownames(r_sub), keep) - r_full <- r_full_nosparse - # values in the subset must match the corresponding entries of the full matrix - expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) - - r_full <- r_full_sparse - r_sub <- ped2com(inbreeding, component = "additive", sparse = T, - keep_ids = keep) - - expect_equal(dim(r_sub), c(length(keep), length(keep))) - expect_equal(rownames(r_sub), keep) - - # values in the subset must match the corresponding entries of the full matrix - expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) -} + keep <- as.character(sample(inbreeding$ID[inbreeding$famID == i], 6)) + + r_sub <- ped2com(inbreeding, + component = "additive", sparse = FALSE, + keep_ids = keep + ) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + r_full <- r_full_nosparse + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + + r_full <- r_full_sparse + r_sub <- ped2com(inbreeding, + component = "additive", sparse = T, + keep_ids = keep + ) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) + } }) @@ -415,8 +440,10 @@ test_that("keep_ids with unknown IDs warns and drops missing entries", { keep <- c(as.character(hazard$ID[1:3]), "BOGUS_ID") expect_warning( - r_sub <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep), + r_sub <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = keep + ), "keep_ids not found" ) expect_equal(nrow(r_sub), 3L) @@ -424,9 +451,9 @@ test_that("keep_ids with unknown IDs warns and drops missing entries", { test_that("keep_ids = NULL returns full pedigree matrix", { data(hazard) - r_full <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL) + r_full <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = NULL + ) expect_equal(nrow(r_full), nrow(hazard)) }) - - diff --git a/tests/testthat/test-buildComponent_chunks.R b/tests/testthat/test-buildComponent_chunks.R index f4172eda..588dc429 100644 --- a/tests/testthat/test-buildComponent_chunks.R +++ b/tests/testthat/test-buildComponent_chunks.R @@ -1,4 +1,3 @@ - # ── chunked tcrossprod per-chunk checkpointing ─────────────────────────────── # Helper: chunk file path matching production code @@ -9,13 +8,19 @@ chunk_path <- function(save_path, i) { test_that("chunked tcrossprod matches standard tcrossprod", { data(hazard) - r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "tcrossprod") - r_chunked_line <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = 3L) + r_standard <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "tcrossprod" + ) + r_chunked_line <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = 3L + ) - r_chunked_prop <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = .5) + r_chunked_prop <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = .5 + ) r_chunked <- r_chunked_prop expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) @@ -26,50 +31,68 @@ test_that("chunked tcrossprod matches standard tcrossprod", { expect_equal(r_standard, r_chunked, tolerance = 1e-10) data(inbreeding) - r_standard <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "tcrossprod") - r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "chunked", chunk_size = 3L,force_symmetric = FALSE) + r_standard <- ped2com(inbreeding, + component = "additive", sparse = T, + transpose_method = "tcrossprod" + ) + r_chunked <- ped2com(inbreeding, + component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L, force_symmetric = FALSE + ) - r_chunked_sym <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "chunked", chunk_size = 3L,force_symmetric = TRUE) + r_chunked_sym <- ped2com(inbreeding, + component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L, force_symmetric = TRUE + ) expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) - expect_gt(# size of matrix in gb r_chunked should be bigger than r_standard due to chunking overhead + expect_gt( # size of matrix in gb r_chunked should be bigger than r_standard due to chunking overhead object.size(r_chunked) / 1e9, - object.size(r_standard) / 1e9) + object.size(r_standard) / 1e9 + ) expect_equal(Matrix::forceSymmetric(r_chunked), - r_chunked_sym, tolerance = 1e-10) + r_chunked_sym, + tolerance = 1e-10 + ) expect_equal(r_standard, - r_chunked_sym - # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision - , tolerance = 1e-10) + r_chunked_sym + # convert to symmetric matrix for comparison since chunked output may not be perfectly symmetric due to numerical precision + , + tolerance = 1e-10 + ) }) test_that("chunked tcrossprod with chunk_size >= nrow behaves like tcrossprod", { data(hazard) - r_standard <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "tcrossprod") - r_chunked <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", - chunk_size = nrow(hazard) + 1L) + r_standard <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "tcrossprod" + ) + r_chunked <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", + chunk_size = nrow(hazard) + 1L + ) expect_equal(as.matrix(r_standard), as.matrix(r_chunked), tolerance = 1e-10) }) - test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", { data(inbreeding) keep <- as.character(inbreeding$ID[5:10]) - r_full <- ped2com(inbreeding, component = "additive", sparse = T, - keep_ids = NULL) - r_sub <- ped2com(inbreeding, component = "additive", sparse = T, - keep_ids = keep) + r_full <- ped2com(inbreeding, + component = "additive", sparse = T, + keep_ids = NULL + ) + r_sub <- ped2com(inbreeding, + component = "additive", sparse = T, + keep_ids = keep + ) expect_equal(dim(r_sub), c(length(keep), length(keep))) expect_equal(rownames(r_sub), keep) @@ -77,14 +100,15 @@ test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", # values in the subset must match the corresponding entries of the full matrix expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) - r_chunked <- ped2com(inbreeding, component = "additive", sparse = T, - transpose_method = "chunked", chunk_size = 3L, - keep_ids = keep,force_symmetric = T) + r_chunked <- ped2com(inbreeding, + component = "additive", sparse = T, + transpose_method = "chunked", chunk_size = 3L, + keep_ids = keep, force_symmetric = T + ) expect_equal(as.matrix(r_sub), as.matrix(r_chunked), tolerance = 1e-10) expect_equal(r_sub, r_chunked, tolerance = 1e-10) expect_equal(r_full[keep, keep], r_chunked, tolerance = 1e-10) - }) test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and size is line-based", { data(hazard) @@ -94,14 +118,17 @@ test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and siz on.exit(unlink(save_path, recursive = TRUE)) chunk_size <- 3L - r_full <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = TRUE, resume = FALSE, save_path = save_path) + r_full <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path + ) n_chunks <- ceiling(nrow(r_full) / chunk_size) for (i in seq_len(n_chunks)) { expect_true(file.exists(chunk_path(save_path, i)), - info = paste("chunk file", i, "should exist")) + info = paste("chunk file", i, "should exist") + ) } }) @@ -113,14 +140,17 @@ test_that("chunked tcrossprod saves per-chunk files when saveable = TRUE and siz on.exit(unlink(save_path, recursive = TRUE)) chunk_size <- .32 - r_full <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = TRUE, resume = FALSE, save_path = save_path) + r_full <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path + ) n_chunks <- ceiling(nrow(r_full) / ceiling(nrow(r_full) * chunk_size)) for (i in seq_len(n_chunks)) { expect_true(file.exists(chunk_path(save_path, i)), - info = paste("chunk file", i, "should exist")) + info = paste("chunk file", i, "should exist") + ) } }) @@ -134,17 +164,21 @@ test_that("chunked tcrossprod resumes from all saved chunk files", { chunk_size <- 3L - r1 <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = TRUE, resume = FALSE, save_path = save_path) + r1 <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path + ) # Remove assembled checkpoint so resume must reconstruct from chunk files unlink(file.path(save_path, "tcrossprod_checkpoint.rds")) unlink(file.path(save_path, "final_matrix.rds")) - r2 <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = FALSE, resume = TRUE, save_path = save_path) + r2 <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = FALSE, resume = TRUE, save_path = save_path + ) expect_equal(as.matrix(r1), as.matrix(r2), tolerance = 1e-10) }) @@ -158,9 +192,11 @@ test_that("chunked tcrossprod partial resume recomputes missing chunks and gives chunk_size <- 3L - r_reference <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = TRUE, resume = FALSE, save_path = save_path) + r_reference <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path + ) n_chunks <- ceiling(nrow(r_reference) / chunk_size) @@ -169,9 +205,11 @@ test_that("chunked tcrossprod partial resume recomputes missing chunks and gives unlink(file.path(save_path, "tcrossprod_checkpoint.rds")) unlink(file.path(save_path, "final_matrix.rds")) - r_partial <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = FALSE, resume = TRUE, save_path = save_path) + r_partial <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = FALSE, resume = TRUE, save_path = save_path + ) expect_equal(as.matrix(r_reference), as.matrix(r_partial), tolerance = 1e-10) }) @@ -185,9 +223,11 @@ test_that("chunked tcrossprod resume loads chunk files not recompute them", { chunk_size <- 3L - ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = TRUE, resume = FALSE, save_path = save_path) + ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = TRUE, resume = FALSE, save_path = save_path + ) # Replace chunk 1 with a sentinel (all zeros) to prove it gets loaded not recomputed sentinel <- readRDS(chunk_path(save_path, 1)) * 0 @@ -196,16 +236,20 @@ test_that("chunked tcrossprod resume loads chunk files not recompute them", { unlink(file.path(save_path, "tcrossprod_checkpoint.rds")) unlink(file.path(save_path, "final_matrix.rds")) - r_resumed <- ped2com(hazard, component = "additive", sparse = FALSE, - transpose_method = "chunked", chunk_size = chunk_size, - saveable = FALSE, resume = TRUE, save_path = save_path) + r_resumed <- ped2com(hazard, + component = "additive", sparse = FALSE, + transpose_method = "chunked", chunk_size = chunk_size, + saveable = FALSE, resume = TRUE, save_path = save_path + ) # Rows from chunk 1 must be all-zero (loaded from sentinel) expect_true(all(as.matrix(r_resumed)[1:chunk_size, ] == 0), - info = "rows from chunk 1 should be all-zero (sentinel)") + info = "rows from chunk 1 should be all-zero (sentinel)" + ) # Rows from chunk 2 must be non-zero (computed normally) expect_true(any(as.matrix(r_resumed)[chunk_size + 1L, ] != 0), - info = "rows from chunk 2 should be non-zero") + info = "rows from chunk 2 should be non-zero" + ) }) # ── tcrossprod_ids checkpoint validation ────────────────────────────────────── @@ -218,17 +262,21 @@ test_that("tcrossprod checkpoint is reused when keep_ids matches saved ids", { on.exit(unlink(save_path, recursive = TRUE)) # First run: saves tcrossprod_checkpoint and tcrossprod_ids - r1 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep, saveable = TRUE, resume = FALSE, - save_path = save_path) + r1 <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = keep, saveable = TRUE, resume = FALSE, + save_path = save_path + ) expect_true(file.exists(file.path(save_path, "tcrossprod_ids.rds"))) expect_equal(readRDS(file.path(save_path, "tcrossprod_ids.rds")), keep) # Second run: same keep_ids → should load checkpoint, not recompute - r2 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep, saveable = FALSE, resume = TRUE, - save_path = save_path) + r2 <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = keep, saveable = FALSE, resume = TRUE, + save_path = save_path + ) expect_equal(r1, r2) }) @@ -238,13 +286,15 @@ test_that("tcrossprod checkpoint is recomputed with warning when keep_ids change keep1 <- as.character(hazard$ID[1:5]) keep2 <- as.character(hazard$ID[6:10]) save_path <- file.path(tempdir(), "test_tcp_ids_mismatch") - unlink(save_path, recursive = TRUE) # guarantee clean state + unlink(save_path, recursive = TRUE) # guarantee clean state dir.create(save_path, showWarnings = FALSE) - ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep1, saveable = TRUE, resume = FALSE, - save_path = save_path) + ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = keep1, saveable = TRUE, resume = FALSE, + save_path = save_path + ) # verify the setup saved what we expect before testing the warning expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) @@ -254,9 +304,11 @@ test_that("tcrossprod checkpoint is recomputed with warning when keep_ids change expect_warning( - r2 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep2, saveable = FALSE, resume = TRUE,verbose = TRUE, - save_path = save_path), + r2 <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = keep2, saveable = FALSE, resume = TRUE, verbose = TRUE, + save_path = save_path + ), "keep_ids do not match" ) expect_equal(rownames(r2), keep2) @@ -269,15 +321,19 @@ test_that("tcrossprod checkpoint saved with keep_ids=NULL is reused on NULL resu dir.create(save_path, showWarnings = FALSE) on.exit(unlink(save_path, recursive = TRUE)) - r1 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL, saveable = TRUE, resume = FALSE, - save_path = save_path) + r1 <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = TRUE, resume = FALSE, + save_path = save_path + ) expect_null(readRDS(file.path(save_path, "tcrossprod_ids.rds"))) - r2 <- ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL, saveable = FALSE, resume = TRUE, - save_path = save_path) + r2 <- ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = FALSE, resume = TRUE, + save_path = save_path + ) expect_equal(r1, r2) }) @@ -286,13 +342,15 @@ test_that("tcrossprod checkpoint saved with NULL warns when resumed with keep_id data(hazard) keep <- as.character(hazard$ID[1:5]) save_path <- file.path(tempdir(), "test_tcp_ids_null_mismatch") - unlink(save_path, recursive = TRUE) # guarantee clean state + unlink(save_path, recursive = TRUE) # guarantee clean state dir.create(save_path, showWarnings = FALSE) on.exit(unlink(save_path, recursive = TRUE)) - ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = NULL, saveable = TRUE, resume = FALSE, - save_path = save_path) + ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = NULL, saveable = TRUE, resume = FALSE, + save_path = save_path + ) # verify the setup saved what we expect before testing the warning expect_true(file.exists(file.path(save_path, "tcrossprod_checkpoint.rds"))) @@ -300,9 +358,11 @@ test_that("tcrossprod checkpoint saved with NULL warns when resumed with keep_id unlink(file.path(save_path, "final_matrix.rds")) # ensure we're testing the checkpoint loading, not final matrix loading expect_warning( - ped2com(hazard, component = "additive", sparse = FALSE, - keep_ids = keep, saveable = FALSE, resume = TRUE, - save_path = save_path), + ped2com(hazard, + component = "additive", sparse = FALSE, + keep_ids = keep, saveable = FALSE, resume = TRUE, + save_path = save_path + ), "keep_ids do not match" ) }) diff --git a/vignettes/v6_pedigree_model_fitting.Rmd b/vignettes/v6_pedigree_model_fitting.Rmd index 9dbf820b..5cd82e01 100644 --- a/vignettes/v6_pedigree_model_fitting.Rmd +++ b/vignettes/v6_pedigree_model_fitting.Rmd @@ -68,10 +68,10 @@ We begin by simulating a multi-generational pedigree using `simulatePedigree()`. set.seed(421) ped <- simulatePedigree( - kpc = 3, # 3 children per couple - Ngen = 4, # 4 generations + kpc = 3, # 3 children per couple + Ngen = 4, # 4 generations sexR = 0.5, # equal sex ratio - marR = 0.6 # 60% mating rate + marR = 0.6 # 60% mating rate ) head(ped) @@ -156,7 +156,6 @@ identified <- id_full$identified identified_text <- "The full model is identified. We can proceed to fit it. However, to illustrate the process of checking identification and refining the model, we will also show how to interpret the details of the identification check. Below, I have provided an unidentified model to demonstrate how to use the `nidp` element of the result to understand which components are confounded." not_identified_text <- "The full model is NOT identified. We will need to refine the model by dropping or fixing some components." - ``` `r if (identified) paste(identified_text) else not_identified_text` @@ -165,14 +164,13 @@ not_identified_text <- "The full model is NOT identified. We will need to refine # show if model is identified identifyComponentModel( - A = add_matrix, - A2 = add_matrix, + A = add_matrix, + A2 = add_matrix, Cn = cn_matrix, Ce = ce_matrix, Mt = mt_matrix, - E = diag(1, nrow(add_matrix)) + E = diag(1, nrow(add_matrix)) ) - ``` With a single pedigree, the 5-component model *may* not be fully identified. The `nidp` element in the result tells us which components are confounded. This is because some relatedness matrices can be linearly dependent -- for example, `ce_matrix` is a matrix of all ones for a single family, and the identity matrix (E) plus other components may span a similar space. In this case, our model is identified, but if it were not, we would see a message like "Variance components are not all identified. (And even if they were, we might not have enough data to estimate them all.) @@ -201,9 +199,9 @@ When a component is not identified with one family, adding families with differe set.seed(99) ped2 <- simulatePedigree(kpc = 4, Ngen = 3, marR = 0.5) |> makeTwins() add2 <- ped2add(ped2, sparse = FALSE) -cn2 <- ped2cn(ped2, sparse = FALSE) -ce2 <- ped2ce(ped2) -mt2 <- ped2mit(ped2, sparse = FALSE) +cn2 <- ped2cn(ped2, sparse = FALSE) +ce2 <- ped2ce(ped2) +mt2 <- ped2mit(ped2, sparse = FALSE) # Check the full model across two families n_combined <- nrow(add_matrix) + nrow(add2) @@ -229,11 +227,11 @@ We define "true" variance components and use the relatedness matrices to constru ```{r simulate-phenotype, eval = has_mvtnorm} # True variance components (proportions of total variance) true_var <- list( - ad2 = 0.50, # additive genetic - cn2 = 0.10, # common nuclear environment - ce2 = 0.00, # common extended environment (set to 0 for identifiability) - mt2 = 0.00, # mitochondrial (set to 0 for simplicity) - ee2 = 0.40 # unique environment (residual) + ad2 = 0.50, # additive genetic + cn2 = 0.10, # common nuclear environment + ce2 = 0.00, # common extended environment (set to 0 for identifiability) + mt2 = 0.00, # mitochondrial (set to 0 for simplicity) + ee2 = 0.40 # unique environment (residual) ) # Build the implied covariance matrix @@ -258,11 +256,9 @@ ytemp <- paste("S", rownames(add_matrix)) ``` ```{r show-phenotype} - if (!exists("y")) { y <- rep(NA, nrow(add_matrix)) } - ``` @@ -298,13 +294,13 @@ start_vars <- list( # Build variance component sub-model vc_model <- buildPedigreeModelCovariance( vars = start_vars, - Vad = TRUE, # estimate additive genetic variance - Vdd = FALSE, # do not estimate dominance - Vcn = TRUE, # estimate common nuclear environment - Vce = TRUE, # estimate common extended environment - Vmt = TRUE, # estimate mitochondrial - Vam = FALSE, # do not estimate A x Mt interaction - Ver = TRUE # estimate unique environment + Vad = TRUE, # estimate additive genetic variance + Vdd = FALSE, # do not estimate dominance + Vcn = TRUE, # estimate common nuclear environment + Vce = TRUE, # estimate common extended environment + Vmt = TRUE, # estimate mitochondrial + Vam = FALSE, # do not estimate A x Mt interaction + Ver = TRUE # estimate unique environment ) vc_model @@ -349,7 +345,7 @@ full_model <- buildPedigreeMx( vars = start_vars, group_models = list(family_group) ) -full_model$submodels +full_model$submodels ``` @@ -493,9 +489,11 @@ estimates_multi <- c( ) comparison_multi <- data.frame( - Component = c("Additive genetic (Vad)", "Common nuclear (Vcn)", - "Common extended (Vce)", "Mitochondrial (Vmt)", - "Unique environment (Ver)"), + Component = c( + "Additive genetic (Vad)", "Common nuclear (Vcn)", + "Common extended (Vce)", "Mitochondrial (Vmt)", + "Unique environment (Ver)" + ), True = truth, Estimated = round(estimates_multi, 4) ) From a4623963d22015b5ba548a4b8b3f4d42ff0e1f3a Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Thu, 26 Mar 2026 10:24:59 -0400 Subject: [PATCH 27/32] clean up yamls --- .github/workflows/{release.yml => release.xml} | 0 codecov.yaml => codecov.xaml | 0 codecov.yml | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{release.yml => release.xml} (100%) rename codecov.yaml => codecov.xaml (100%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.xml similarity index 100% rename from .github/workflows/release.yml rename to .github/workflows/release.xml diff --git a/codecov.yaml b/codecov.xaml similarity index 100% rename from codecov.yaml rename to codecov.xaml diff --git a/codecov.yml b/codecov.yml index 6c208bba..519a4302 100644 --- a/codecov.yml +++ b/codecov.yml @@ -13,5 +13,5 @@ coverage: project: default: target: auto - threshold: 1% + threshold: 2% informational: false From 25623307912a4dd4388c9b557e01f65d42095590 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Thu, 26 Mar 2026 10:52:06 -0400 Subject: [PATCH 28/32] all keep_ids to be used on all matrices --- R/buildComponent.R | 71 ++++++++++++++++++++++++++++++-------- R/buildComponentWrappers.R | 23 +++++++++++- man/dot-subsetKeepIds.Rd | 30 ++++++++++++++++ man/ped2add.Rd | 2 +- man/ped2ce.Rd | 15 +++++++- man/ped2cn.Rd | 3 ++ man/ped2gen.Rd | 3 ++ man/ped2mit.Rd | 3 ++ 8 files changed, 133 insertions(+), 17 deletions(-) create mode 100644 man/dot-subsetKeepIds.Rd diff --git a/R/buildComponent.R b/R/buildComponent.R index 6fb8162f..2989a6d6 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -316,6 +316,13 @@ ped2com <- function(ped, component, } if (config$component == "generation") { # no need to do the rest + gen <- .subsetKeepIds( + component = gen, + keep_ids = config$keep_ids, + available_ids = rownames(r), + config = config, + verbose_message = "Subsetting generation component to %d target individuals\n" + ) return(gen) } else { if (config$verbose == TRUE) { @@ -360,20 +367,14 @@ ped2com <- function(ped, component, # Subset rows of r2 to target individuals if requested. # All columns are kept so dot products use the full ancestry paths. if (!is.null(config$keep_ids)) { - idx <- match(config$keep_ids, rownames(r2)) - missing <- config$keep_ids[is.na(idx)] - if (length(missing) > 0) { - warning( - length(missing), " keep_ids not found in pedigree and will be dropped: ", - paste(Matrix::head(missing, 5), collapse = ", "), - if (length(missing) > 5) " ..." else "" - ) - } - idx <- idx[!is.na(idx)] - if (config$verbose == TRUE) { - cat(sprintf("Subsetting r2 to %d target individuals before tcrossprod\n", length(idx))) - } - r2 <- r2[idx, , drop = FALSE] + r2 <- .subsetKeepIds( + component = r2, + keep_ids = config$keep_ids, + available_ids = rownames(r2), + config = config, + verbose_message = "Subsetting r2 to %d target individuals before tcrossprod\n", + drop = FALSE + ) } use_tcrossprod_checkpoint <- FALSE @@ -840,3 +841,45 @@ loadOrComputeCheckpoint <- function(file, compute_fn, } list_of_adjacencies } + + +#' Subset output to requested IDs +#' @inheritParams ped2com +#' @param component A component to subset. +#' @param keep_ids Character vector of IDs to retain. +#' @param available_ids Character vector of IDs available in \code{x}. +#' @param verbose_message Character. Message prefix to print when \code{config$verbose == TRUE}. +#' @param drop logical. Passed to \code{[} when subsetting matrices. +#' @keywords internal +.subsetKeepIds <- function(component, keep_ids = NULL, available_ids, config, + verbose_message = "Subsetting to %d target individuals\n", + drop = FALSE) { + if (is.null(keep_ids)) { + return(component) + } + + idx <- match(keep_ids, available_ids) + missing <- keep_ids[is.na(idx)] + + if (length(missing) > 0) { + warning( + length(missing), " keep_ids not found in pedigree and will be dropped: ", + paste(Matrix::head(missing, 5), collapse = ", "), + if (length(missing) > 5) " ..." else "" + ) + } + + idx <- idx[!is.na(idx)] + + if (config$verbose == TRUE) { + cat(sprintf(verbose_message, length(idx))) + } + + if (is.matrix(component) || methods::is(component, "Matrix")) { + component <- component[idx, , drop = drop] + } else { + component <- component[idx] + } + + component +} diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R index d6cd7c4a..fbaed6ed 100644 --- a/R/buildComponentWrappers.R +++ b/R/buildComponentWrappers.R @@ -19,7 +19,7 @@ ped2add <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, compress = TRUE, mz_twins = FALSE, mz_method = "addtwins", - force_symmetric = FALSE, + force_symmetric = TRUE, ...) { ped2com( ped = ped, @@ -59,6 +59,7 @@ ped2mit <- ped2mt <- function(ped, max_gen = 25, flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + keep_ids = NULL, adjacency_method = "direct", saveable = FALSE, resume = FALSE, @@ -79,6 +80,7 @@ ped2mit <- ped2mt <- function(ped, max_gen = 25, flatten_diag = flatten_diag, standardize_colnames = standardize_colnames, transpose_method = transpose_method, + keep_ids = keep_ids, adjacency_method = adjacency_method, saveable = saveable, resume = resume, @@ -100,6 +102,7 @@ ped2cn <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, gc = FALSE, flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + keep_ids = NULL, saveable = FALSE, resume = FALSE, save_rate = 5, @@ -121,6 +124,7 @@ ped2cn <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, flatten_diag = flatten_diag, standardize_colnames = standardize_colnames, transpose_method = transpose_method, + keep_ids = keep_ids, saveable = saveable, resume = resume, save_rate_gen = save_rate_gen, @@ -140,6 +144,7 @@ ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, gc = FALSE, flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + keep_ids = NULL, saveable = FALSE, resume = FALSE, save_rate = 5, @@ -161,6 +166,7 @@ ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, flatten_diag = flatten_diag, standardize_colnames = standardize_colnames, transpose_method = transpose_method, + keep_ids = keep_ids, saveable = saveable, resume = resume, save_rate_gen = save_rate_gen, @@ -180,6 +186,21 @@ ped2gen <- function(ped, max_gen = 25, sparse = TRUE, verbose = FALSE, #' @export #' ped2ce <- function(ped, personID = "ID", + keep_ids = NULL, + sparse = FALSE, verbose = FALSE, ...) { + if (!is.null(keep_ids)) { + ped <- ped[ped[[personID]] %in% keep_ids, ] + } + if (sparse) { + mat <- Matrix::sparseMatrix( + i = seq_len(nrow(ped)), + j = seq_len(nrow(ped)), + x = 1, + dimnames = list(ped[[personID]], ped[[personID]]) + ) + return(mat) + } else { matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped[[personID]], ped[[personID]])) + } } diff --git a/man/dot-subsetKeepIds.Rd b/man/dot-subsetKeepIds.Rd new file mode 100644 index 00000000..b05ac9c8 --- /dev/null +++ b/man/dot-subsetKeepIds.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/buildComponent.R +\name{.subsetKeepIds} +\alias{.subsetKeepIds} +\title{Subset output to requested IDs} +\usage{ +.subsetKeepIds( + component, + keep_ids = NULL, + available_ids, + config, + verbose_message = "Subsetting to \%d target individuals\\n", + drop = FALSE +) +} +\arguments{ +\item{component}{A component to subset.} + +\item{keep_ids}{Character vector of IDs to retain.} + +\item{available_ids}{Character vector of IDs available in \code{x}.} + +\item{verbose_message}{Character. Message prefix to print when \code{config$verbose == TRUE}.} + +\item{drop}{logical. Passed to \code{[} when subsetting matrices.} +} +\description{ +Subset output to requested IDs +} +\keyword{internal} diff --git a/man/ped2add.Rd b/man/ped2add.Rd index 78494229..e62a3c01 100644 --- a/man/ped2add.Rd +++ b/man/ped2add.Rd @@ -25,7 +25,7 @@ ped2add( compress = TRUE, mz_twins = FALSE, mz_method = "addtwins", - force_symmetric = FALSE, + force_symmetric = TRUE, ... ) } diff --git a/man/ped2ce.Rd b/man/ped2ce.Rd index e00489cc..36002070 100644 --- a/man/ped2ce.Rd +++ b/man/ped2ce.Rd @@ -4,13 +4,26 @@ \alias{ped2ce} \title{Take a pedigree and turn it into an extended environmental relatedness matrix} \usage{ -ped2ce(ped, personID = "ID", ...) +ped2ce( + ped, + personID = "ID", + keep_ids = NULL, + sparse = FALSE, + verbose = FALSE, + ... +) } \arguments{ \item{ped}{a pedigree dataset. Needs ID, momID, and dadID columns} \item{personID}{Character. Column name for individual IDs.} +\item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} + +\item{sparse}{logical. If TRUE, use and return sparse matrices from Matrix package} + +\item{verbose}{logical. If TRUE, print progress through stages of algorithm} + \item{...}{additional arguments to be passed to \code{\link{ped2com}}} } \description{ diff --git a/man/ped2cn.Rd b/man/ped2cn.Rd index 1bfe548b..bdc48679 100644 --- a/man/ped2cn.Rd +++ b/man/ped2cn.Rd @@ -13,6 +13,7 @@ ped2cn( flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + keep_ids = NULL, saveable = FALSE, resume = FALSE, save_rate = 5, @@ -42,6 +43,8 @@ ped2cn( \item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} +\item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} + \item{saveable}{logical. If TRUE, save the intermediate results to disk} \item{resume}{logical. If TRUE, resume from a checkpoint} diff --git a/man/ped2gen.Rd b/man/ped2gen.Rd index ec9feef5..6c53c54f 100644 --- a/man/ped2gen.Rd +++ b/man/ped2gen.Rd @@ -13,6 +13,7 @@ ped2gen( flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + keep_ids = NULL, saveable = FALSE, resume = FALSE, save_rate = 5, @@ -42,6 +43,8 @@ ped2gen( \item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} +\item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} + \item{saveable}{logical. If TRUE, save the intermediate results to disk} \item{resume}{logical. If TRUE, resume from a checkpoint} diff --git a/man/ped2mit.Rd b/man/ped2mit.Rd index 81db86c0..0e950493 100644 --- a/man/ped2mit.Rd +++ b/man/ped2mit.Rd @@ -14,6 +14,7 @@ ped2mit( flatten_diag = FALSE, standardize_colnames = TRUE, transpose_method = "tcrossprod", + keep_ids = NULL, adjacency_method = "direct", saveable = FALSE, resume = FALSE, @@ -43,6 +44,8 @@ ped2mit( \item{transpose_method}{character. The method to use for computing the transpose. Options are "tcrossprod", "crossprod", "star", or "chunked"} +\item{keep_ids}{character vector of IDs to retain in the final relatedness matrix. When supplied, only the rows of \code{r2} corresponding to these IDs are used in the tcrossprod, so the result is a \code{length(keep_ids) x length(keep_ids)} matrix. All columns of \code{r2} are retained during the multiplication so relatedness values remain correct. IDs not found in the pedigree are silently dropped with a warning.} + \item{adjacency_method}{character. The method to use for computing the adjacency matrix. Options are "loop", "indexed", direct or beta} \item{saveable}{logical. If TRUE, save the intermediate results to disk} From 17ddb4ddcb1033846ccfa52e5117350a145a4157 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Thu, 26 Mar 2026 13:14:57 -0400 Subject: [PATCH 29/32] Add ignores --- .Rbuildignore | 2 ++ R/buildComponent.R | 2 +- data-raw/optimizing_transpose.R | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index c5aa8e6d..fced4e44 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -24,6 +24,7 @@ CITATION.cff$ ^checkParents\.X ^checklist.yml$ ^codecov\.yml$ +^codecov\.xaml$ ^cran-comments\.md$ ^data-raw$ ^doc$ @@ -34,3 +35,4 @@ CITATION.cff$ ^revdep$ ^test-clean\.X ^vignettes/articles$ +^.claude$ diff --git a/R/buildComponent.R b/R/buildComponent.R index 2989a6d6..9983f0f9 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -874,7 +874,7 @@ loadOrComputeCheckpoint <- function(file, compute_fn, if (config$verbose == TRUE) { cat(sprintf(verbose_message, length(idx))) } - +# consequence is missing data if (is.matrix(component) || methods::is(component, "Matrix")) { component <- component[idx, , drop = drop] } else { diff --git a/data-raw/optimizing_transpose.R b/data-raw/optimizing_transpose.R index 587859df..b1428566 100644 --- a/data-raw/optimizing_transpose.R +++ b/data-raw/optimizing_transpose.R @@ -9,12 +9,12 @@ devtools::load_all(".") # --------------------------- cfg <- list( seed = 1164127, - Ngen_base = 2, - reps = 10, + Ngen_base = 3, + reps = 2, all_scenarios = TRUE, # set to TRUE to run all scenarios defined below include_highgen = TRUE, include_1gen = FALSE, - include_lowgen = FALSE + include_lowgen = TRUE ) cfg$gen_twin <- ceiling(cfg$Ngen_base - 1) @@ -47,7 +47,7 @@ levels <- list( ), # Simulation-side factors (simulatePedigree) - kpc = 5, # set to c(2, 3, 4) to vary + kpc = 4, # set to c(2, 3, 4) to vary sexR = 0.50, # sometimes fails above .5 marR = c(0.9), # set to c(0.6, 0.8, 0.9) to vary sim_beta = TRUE, # set to c(TRUE, FALSE) if you ever want to vary From effa5cf3eef8bb52220e51c694d895e125001b9e Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Thu, 26 Mar 2026 14:57:44 -0400 Subject: [PATCH 30/32] Update test-buildComponent.R --- tests/testthat/test-buildComponent.R | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index d3030895..9800a7cc 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -435,6 +435,58 @@ test_that("keep_ids subset produces correct relatedness values across all famili }) +test_that("keep_ids subset produces correct relatedness values across all families", { + library(ggpedigree) + data(ASOIAF) +df <-ASOIAF |> dplyr::rename(ID = id) + + r_full_sparse <- ped2com(df, + component = "additive", sparse = TRUE, + keep_ids = NULL, + mz_twins = FALSE + ) + for (i in unique(df$famID)) { + n_rows <- sum(df$famID == i) + if (n_rows < 3) { + next + } + keep <- as.character(sample(df$ID[df$famID == i], min(15,n_rows))) + + + r_full <- r_full_sparse + r_sub <- ped2com(df, + component = "additive", sparse = TRUE, + keep_ids = keep, + mz_twins = FALSE + ) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10, info = paste("Family", i)) + + #entirely random subset of IDs across the whole dataset (not just within family) + keep <- as.character(sample(df$ID, 15)) + + + r_full <- r_full_sparse + r_sub <- ped2com(df, + component = "additive", sparse = TRUE, + keep_ids = keep, + mz_twins = FALSE + ) + + expect_equal(dim(r_sub), c(length(keep), length(keep))) + expect_equal(rownames(r_sub), keep) + + # values in the subset must match the corresponding entries of the full matrix + expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10, info = paste(keep)) + } +}) + + + test_that("keep_ids with unknown IDs warns and drops missing entries", { data(hazard) keep <- c(as.character(hazard$ID[1:3]), "BOGUS_ID") From e29f0a28d2c036fb55c46fa95b367b88e15ebfcc Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Thu, 26 Mar 2026 22:03:53 -0400 Subject: [PATCH 31/32] TRUE, not T --- R/buildComponent.R | 2 +- R/buildComponentWrappers.R | 2 +- tests/testthat/test-buildComponent.R | 24 ++++++++++----------- tests/testthat/test-buildComponent_chunks.R | 14 ++++++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 9983f0f9..2802b229 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -874,7 +874,7 @@ loadOrComputeCheckpoint <- function(file, compute_fn, if (config$verbose == TRUE) { cat(sprintf(verbose_message, length(idx))) } -# consequence is missing data + # consequence is missing data if (is.matrix(component) || methods::is(component, "Matrix")) { component <- component[idx, , drop = drop] } else { diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R index fbaed6ed..b0344a51 100644 --- a/R/buildComponentWrappers.R +++ b/R/buildComponentWrappers.R @@ -201,6 +201,6 @@ ped2ce <- function(ped, personID = "ID", ) return(mat) } else { - matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped[[personID]], ped[[personID]])) + matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped[[personID]], ped[[personID]])) } } diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 9800a7cc..c5c2e9fe 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -438,26 +438,26 @@ test_that("keep_ids subset produces correct relatedness values across all famili test_that("keep_ids subset produces correct relatedness values across all families", { library(ggpedigree) data(ASOIAF) -df <-ASOIAF |> dplyr::rename(ID = id) + df <- ASOIAF |> dplyr::rename(ID = id) r_full_sparse <- ped2com(df, - component = "additive", sparse = TRUE, - keep_ids = NULL, - mz_twins = FALSE + component = "additive", sparse = TRUE, + keep_ids = NULL, + mz_twins = FALSE ) for (i in unique(df$famID)) { n_rows <- sum(df$famID == i) if (n_rows < 3) { next } - keep <- as.character(sample(df$ID[df$famID == i], min(15,n_rows))) + keep <- as.character(sample(df$ID[df$famID == i], min(15, n_rows))) r_full <- r_full_sparse r_sub <- ped2com(df, - component = "additive", sparse = TRUE, - keep_ids = keep, - mz_twins = FALSE + component = "additive", sparse = TRUE, + keep_ids = keep, + mz_twins = FALSE ) expect_equal(dim(r_sub), c(length(keep), length(keep))) @@ -466,15 +466,15 @@ df <-ASOIAF |> dplyr::rename(ID = id) # values in the subset must match the corresponding entries of the full matrix expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10, info = paste("Family", i)) - #entirely random subset of IDs across the whole dataset (not just within family) + # entirely random subset of IDs across the whole dataset (not just within family) keep <- as.character(sample(df$ID, 15)) r_full <- r_full_sparse r_sub <- ped2com(df, - component = "additive", sparse = TRUE, - keep_ids = keep, - mz_twins = FALSE + component = "additive", sparse = TRUE, + keep_ids = keep, + mz_twins = FALSE ) expect_equal(dim(r_sub), c(length(keep), length(keep))) diff --git a/tests/testthat/test-buildComponent_chunks.R b/tests/testthat/test-buildComponent_chunks.R index 588dc429..a89e7aa5 100644 --- a/tests/testthat/test-buildComponent_chunks.R +++ b/tests/testthat/test-buildComponent_chunks.R @@ -32,16 +32,16 @@ test_that("chunked tcrossprod matches standard tcrossprod", { data(inbreeding) r_standard <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "tcrossprod" ) r_chunked <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "chunked", chunk_size = 3L, force_symmetric = FALSE ) r_chunked_sym <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "chunked", chunk_size = 3L, force_symmetric = TRUE ) @@ -86,11 +86,11 @@ test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", keep <- as.character(inbreeding$ID[5:10]) r_full <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = NULL ) r_sub <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = keep ) @@ -101,9 +101,9 @@ test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) r_chunked <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "chunked", chunk_size = 3L, - keep_ids = keep, force_symmetric = T + keep_ids = keep, force_symmetric = TRUE ) expect_equal(as.matrix(r_sub), as.matrix(r_chunked), tolerance = 1e-10) From c2b938a5633121262a69f7a061fde1ebae15e850 Mon Sep 17 00:00:00 2001 From: Mason Garrison Date: Thu, 26 Mar 2026 22:03:53 -0400 Subject: [PATCH 32/32] TRUE, not T --- R/buildComponent.R | 2 +- R/buildComponentWrappers.R | 2 +- tests/testthat/test-buildComponent.R | 32 ++++++++++----------- tests/testthat/test-buildComponent_chunks.R | 14 ++++----- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/R/buildComponent.R b/R/buildComponent.R index 9983f0f9..2802b229 100644 --- a/R/buildComponent.R +++ b/R/buildComponent.R @@ -874,7 +874,7 @@ loadOrComputeCheckpoint <- function(file, compute_fn, if (config$verbose == TRUE) { cat(sprintf(verbose_message, length(idx))) } -# consequence is missing data + # consequence is missing data if (is.matrix(component) || methods::is(component, "Matrix")) { component <- component[idx, , drop = drop] } else { diff --git a/R/buildComponentWrappers.R b/R/buildComponentWrappers.R index fbaed6ed..b0344a51 100644 --- a/R/buildComponentWrappers.R +++ b/R/buildComponentWrappers.R @@ -201,6 +201,6 @@ ped2ce <- function(ped, personID = "ID", ) return(mat) } else { - matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped[[personID]], ped[[personID]])) + matrix(1, nrow = nrow(ped), ncol = nrow(ped), dimnames = list(ped[[personID]], ped[[personID]])) } } diff --git a/tests/testthat/test-buildComponent.R b/tests/testthat/test-buildComponent.R index 9800a7cc..ca733e9c 100644 --- a/tests/testthat/test-buildComponent.R +++ b/tests/testthat/test-buildComponent.R @@ -379,11 +379,11 @@ test_that("keep_ids subset produces correct relatedness values", { r_full <- ped2com(hazard, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = NULL ) r_sub <- ped2com(hazard, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = keep ) @@ -403,7 +403,7 @@ test_that("keep_ids subset produces correct relatedness values across all famili ) r_full_sparse <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = NULL ) for (i in unique(inbreeding$famID)) { @@ -422,7 +422,7 @@ test_that("keep_ids subset produces correct relatedness values across all famili r_full <- r_full_sparse r_sub <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = keep ) @@ -438,26 +438,26 @@ test_that("keep_ids subset produces correct relatedness values across all famili test_that("keep_ids subset produces correct relatedness values across all families", { library(ggpedigree) data(ASOIAF) -df <-ASOIAF |> dplyr::rename(ID = id) + df <- ASOIAF |> dplyr::rename(ID = id) r_full_sparse <- ped2com(df, - component = "additive", sparse = TRUE, - keep_ids = NULL, - mz_twins = FALSE + component = "additive", sparse = TRUE, + keep_ids = NULL, + mz_twins = FALSE ) for (i in unique(df$famID)) { n_rows <- sum(df$famID == i) if (n_rows < 3) { next } - keep <- as.character(sample(df$ID[df$famID == i], min(15,n_rows))) + keep <- as.character(sample(df$ID[df$famID == i], min(15, n_rows))) r_full <- r_full_sparse r_sub <- ped2com(df, - component = "additive", sparse = TRUE, - keep_ids = keep, - mz_twins = FALSE + component = "additive", sparse = TRUE, + keep_ids = keep, + mz_twins = FALSE ) expect_equal(dim(r_sub), c(length(keep), length(keep))) @@ -466,15 +466,15 @@ df <-ASOIAF |> dplyr::rename(ID = id) # values in the subset must match the corresponding entries of the full matrix expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10, info = paste("Family", i)) - #entirely random subset of IDs across the whole dataset (not just within family) + # entirely random subset of IDs across the whole dataset (not just within family) keep <- as.character(sample(df$ID, 15)) r_full <- r_full_sparse r_sub <- ped2com(df, - component = "additive", sparse = TRUE, - keep_ids = keep, - mz_twins = FALSE + component = "additive", sparse = TRUE, + keep_ids = keep, + mz_twins = FALSE ) expect_equal(dim(r_sub), c(length(keep), length(keep))) diff --git a/tests/testthat/test-buildComponent_chunks.R b/tests/testthat/test-buildComponent_chunks.R index 588dc429..a89e7aa5 100644 --- a/tests/testthat/test-buildComponent_chunks.R +++ b/tests/testthat/test-buildComponent_chunks.R @@ -32,16 +32,16 @@ test_that("chunked tcrossprod matches standard tcrossprod", { data(inbreeding) r_standard <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "tcrossprod" ) r_chunked <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "chunked", chunk_size = 3L, force_symmetric = FALSE ) r_chunked_sym <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "chunked", chunk_size = 3L, force_symmetric = TRUE ) @@ -86,11 +86,11 @@ test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", keep <- as.character(inbreeding$ID[5:10]) r_full <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = NULL ) r_sub <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, keep_ids = keep ) @@ -101,9 +101,9 @@ test_that("chunked tcrossprod matches standard tcrossprod when also subsetted", expect_equal(r_sub, r_full[keep, keep], tolerance = 1e-10) r_chunked <- ped2com(inbreeding, - component = "additive", sparse = T, + component = "additive", sparse = TRUE, transpose_method = "chunked", chunk_size = 3L, - keep_ids = keep, force_symmetric = T + keep_ids = keep, force_symmetric = TRUE ) expect_equal(as.matrix(r_sub), as.matrix(r_chunked), tolerance = 1e-10)