Quality assessment and preprocessing across omics layers

Practical 16: Genomics, systems biology and multi-omics

Learning objectives

Compare assay-specific scales; audit sample and feature missingness; define transparent exclusions and preprocessing choices.

Biological question and data

Can the same quality rule and transformation be applied indiscriminately to counts, protein abundances and metabolites?

Counts are nonnegative integer measurements; protein and metabolite matrices are supplied log2 abundances. Missing proteins are deliberately inserted. All samples are fictional animals with explicit metadata.

No biological download is required. Numerical inputs are hypothetical, not observed animal data. The runnable examples use base R. Count and abundance units are specified where used.

1. Audit each assay separately

Check IDs, dimensions, missingness and the supplied measurement scale.

Show R code
helper_dir <- if (dir.exists("R")) "R" else "../R"
stopifnot(file.exists(file.path(helper_dir,"teaching_data.R")))
source(file.path(helper_dir,"teaching_data.R"))
d <- teaching_data()
assays <- list(counts=d$counts,protein=d$protein_missing,metabolite=d$metabolite)
audit <- do.call(rbind,lapply(names(assays),function(name) {
 X <- assays[[name]]
 stopifnot(identical(colnames(X),d$metadata$animal))
 data.frame(assay=name,features=nrow(X),animals=ncol(X),missing=sum(is.na(X)),
 observed_min=min(X,na.rm=TRUE),observed_max=max(X,na.rm=TRUE))
}))
audit
       assay features animals missing observed_min observed_max
1     counts       24      48       0    12.000000  1218.000000
2    protein        8      48      11     6.248562    12.117980
3 metabolite        6      48       0     2.356815     9.467836

The missingness total is not interchangeable with a count of missing animals. Different assays have different physical and statistical meanings.

2. Inspect missingness by feature and group

Quantify before choosing a policy. Missingness may depend on the measurement process.

Show R code
P <- d$protein_missing
missing_feature <- rowMeans(is.na(P))
missing_animal <- colSums(is.na(P))
data.frame(feature=rownames(P),fraction_missing=missing_feature)
            feature fraction_missing
protein01 protein01        0.0625000
protein02 protein02        0.1666667
protein03 protein03        0.0000000
protein04 protein04        0.0000000
protein05 protein05        0.0000000
protein06 protein06        0.0000000
protein07 protein07        0.0000000
protein08 protein08        0.0000000
Show R code
aggregate(missing_animal,list(diet=d$metadata$diet),mean)
        diet         x
1    control 0.2083333
2 supplement 0.2500000
Show R code
stopifnot(sum(is.na(P))==11,sum(missing_animal>0)==9)

Nine animals have at least one missing protein value, totaling eleven feature-level NAs. The mechanism is supplied insertion here; real missingness needs investigation.

3. Define a stated feature policy and transform correctly

The example retains features with no missing measurements for descriptive PCA. The threshold is a teaching choice.

Show R code
keep <- missing_feature==0
complete <- P[keep,,drop=FALSE]
count_log <- log2(sweep(d$counts,2,d$exposure,"/")+1)
c(retained_proteins=nrow(complete),removed_proteins=sum(!keep))
retained_proteins  removed_proteins 
                6                 2 
Show R code
stopifnot(nrow(complete)==6,!anyNA(complete),all(is.finite(count_log)))

Protein values are already log2; logging them again would change their interpretation. The count transformation is descriptive, not a differential-expression model.

4. Expose selection by completeness

Complete-case integration can exclude a disproportionate part of one group. In this hypothetical example, only the treated group loses assay observations.

Show R code
qc_example <- data.frame(group=rep(c('C','T'),each=4),
 layer1=1:8,layer2=c(1:4,5,NA,NA,NA))
qc_example$complete <- complete.cases(qc_example[c('layer1','layer2')])
with(qc_example,table(group,complete))
     complete
group FALSE TRUE
    C     0    4
    T     3    1

5. State what each QC rule protects

A sample-level exclusion changes the subject set; feature filtering changes the measurement universe. An RNA count filter, protein observation-rate filter and metabolite blank threshold address different processes. Keep the rule and its justification tied to the assay rather than forcing all layers through one numerical threshold.

Report before/after counts, group balance, units and transformations. For prediction, estimate imputation and scaling within training splits. For descriptive integration, explain the subset represented and investigate whether missingness depends on health, treatment or processing.

Interpretation challenge

Does complete-case analysis guarantee an unbiased integrated dataset?

No. Completeness can depend on the phenotype or treatment. The retained subset may differ systematically from the original population, even if the resulting matrix contains no missing values.

Interpretation and limits

Complete-feature selection excludes signals with missingness and can change the biological question. Imputation and filtering should be justified and fitted within training splits for prediction. Panel counts are not true total sequencing depth, and an abundance profile cannot replace identification/platform QC.

Exercises

  1. Why is a universal log transformation unsafe?
  2. Is deleting every animal with any NA unbiased?
  3. Which preprocessing decisions must stay within training data?
  1. Measurements may already be logged, include legitimate zeros, or have different scales.
  2. Not necessarily; excluded animals can differ systematically.
  3. Data-derived filtering, scaling, imputation, feature selection and model tuning.

Continue learning

B04 Programming, B06 Transcriptomics, B08 Proteomics and B15 Integration.

Continue with proteomics, metabolomics or exploration. Return to the practical index or the unified map.