Create a new synthetic sample in a qseaSet by mixing reads from two existing samples in user-specified proportions. Useful for benchmarking, downsampling experiments, or simulating tumour–normal mixtures.

mixSamples(
  qseaSet,
  sample1,
  sample2,
  nReadsTotal,
  proportion,
  newName = NULL,
  groupName = NULL,
  onlyNew = FALSE,
  renormalise = TRUE
)

Arguments

qseaSet

qseaSet. The input object containing the two source samples.

sample1

character(1). First sample name, contributing proportion * nReadsTotal reads.

sample2

character(1). Second sample name, contributing the remainder of reads.

nReadsTotal

integer(1). Total number of reads to simulate in the new mixed sample. Must be >= 0.

proportion

numeric(1). Proportion of reads taken from sample1. Must be in [0, 1]. The remaining 1 - proportion reads are taken from sample2.

newName

character(1) or NULL. Name for the new synthetic sample. Default: NULL (a name is generated automatically, e.g., "Mix_<sample1>_<sample2>_<proportion>").

groupName

character(1) or NULL. Group name for the new sample recorded in the sampleTable. Default: NULL (uses newName).

onlyNew

logical(1). If TRUE, return only the synthetic sample. If FALSE, return the original qseaSet with the new sample appended. Default: FALSE.

renormalise

logical(1). Whether to run addNormalisation() on the result. For efficiency, set to FALSE when creating multiple mixtures and run normalisation once at the end. Default: TRUE.

Value

A qseaSet containing the new synthetic sample:

  • If onlyNew = TRUE, a qseaSet with one (mixed) sample.

  • If onlyNew = FALSE, the input qseaSet plus the mixed sample. The sampleTable, counts, and relevant slots are updated consistently.

Details

Note that if the qseaSet windows have been filtered prior to using this, the fraction of fragments present in the current qseaSet is calculated, such that the total number of reads would have been approximately nReadsTotal. E.g. if there are 50% of the total fragments in the windows present in the current samples, 0.5*nReadsTotal fragments will be sampled.

  • Input validation ensures sample1/sample2 exist, proportion in [0,1], and nReadsTotal is non-negative.

  • The mixing strategy (e.g., proportional allocation vs sampling) follows the package’s implementation; set renormalise = TRUE to recompute offsets/enrichment after adding the new sample if required by your workflow.

Examples

data(exampleTumourNormal, package = "mesa")


# Mix two samples 50/50 into ~100k total fragments; append to the qseaSet
exampleTumourNormal %>%
    mixSamples("Colon1_T",
        "Colon1_N",
        nReadsTotal = 100000,
        proportion = 0.5,
        renormalise = FALSE
    ) %>%
    # Only a few reads are included in this small subset of windows (82):
    getCountTable() %>%
    pull(Mix_Colon1_T_Colon1_N_0.5) %>%
    sum()
#> Mix_Colon1_T_Colon1_N_0.5
#> Mixing 50000 reads from Colon1_T with 50000 reads from Colon1_N.
#> Joining with `by = join_by(seqnames, start, end, width, strand, CpG_density)`
#> Generating table of counts values for 819 regions across 11 samples.
#> [1] 82


# Mix two samples 80/20 and return only the synthetic sample, with an
# explicit name and group
exampleTumourNormal %>%
    mixSamples("Colon1_T", "Colon1_N",
        nReadsTotal = 50000,
        proportion  = 0.8,
        newName     = "Mix_Colon1_T_0.8_Colon1_N_0.2",
        groupName   = "Synthetic",
        onlyNew     = TRUE,
        renormalise = FALSE
    ) %>%
    # Only a few reads are included in this small subset of windows (45):
    getCountTable() %>%
    dplyr::pull(Mix_Colon1_T_0.8_Colon1_N_0.2) %>%
    sum()
#> Mix_Colon1_T_0.8_Colon1_N_0.2
#> Mixing 40000 reads from Colon1_T with 10000 reads from Colon1_N.
#> Generating table of counts values for 819 regions across 1 samples.
#> [1] 45