--- title: "Use Case: Genomic Data Smoothing" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Use Case: Genomic Data Smoothing} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` LOWESS for methylation profiles, ChIP-seq signals, and other genomic data. ## Overview Genomic data often contains noise from sequencing depth variation, PCR artifacts, or biological heterogeneity. LOWESS smoothing helps reveal underlying patterns. --- ## Methylation Profile Smoothing ### The Challenge DNA methylation data (from bisulfite sequencing or arrays) shows position-dependent patterns that can be obscured by measurement noise. ### Solution A small `fraction = 0.1` lets LOWESS follow fine-scale spatial structure without smearing the transitions between methylated and unmethylated regions. `intervals = intervals_opts(confidence = 0.95)` produces uncertainty bands that naturally widen at positions with sparser CpG coverage, making low-confidence segments immediately apparent in the plot. ```{r use_case_genomics_1} library(rfastlowess) positions <- seq(0, 99000, by = 1000) observed <- 50 + sin(positions / 1000) * 20 + 5 # positions and observed are your methylation data model <- Lowess( fraction = 0.1, iterations = 3, intervals = intervals_opts(confidence = 0.95) ) result <- fit(model, positions, observed) # Smoothed profile in result$y # CI bounds in result$confidence_lower/upper plot(positions, observed, pch = ".", col = "gray", xlab = "Genomic Position (bp)", ylab = "Methylation Level", main = "Methylation Profile Smoothing") lines(result$x, result$y, col = "blue", lwd = 2) lines(result$x, result$confidence_lower, col = "blue", lty = 2) lines(result$x, result$confidence_upper, col = "blue", lty = 2) legend("topright", c("Observed", "Smoothed", "95% CI"), pch = c(1, NA, NA), lty = c(NA, 1, 2), col = c("gray", "blue", "blue")) cat(sprintf( "95%% CI: [%.4f, %.4f]\n", result$confidence_lower[1], result$confidence_upper[1] )) ``` --- ## ChIP-seq Signal Smoothing ### Application ChIP-seq experiments produce sparse, noisy coverage data. LOWESS can help identify binding regions. `fraction = 0.05` provides high spatial resolution — important for resolving narrow binding peaks that would otherwise be smeared into the background. The larger `iterations = 5` is deliberate: Poisson-distributed read counts produce tall, isolated spikes, and extra robustness iterations progressively down-weight them so the estimated background level is not inflated by a handful of extreme counts. ```{r use_case_genomics_2} library(rfastlowess) positions <- seq(0, 99000, by = 1000) signal <- 50 + sin(positions / 1000) * 20 + 5 model <- Lowess( fraction = 0.05, iterations = 5 ) result <- fit(model, positions, signal) # Identify peaks above threshold peak_count <- sum(result$y > 65.0) cat(sprintf("y[0]: %.4f\n", result$y[1])) cat(sprintf("Peak count: %d\n", peak_count)) ``` --- ## Large Genome Coverage (Streaming) For whole-genome data that doesn't fit in memory: ```{r use_case_genomics_3} library(rfastlowess) positions <- seq(0, 10000, by = 10) coverage <- 50 + sin(positions / 100) * 20 + 5.0 model <- StreamingLowess( fraction = 0.05, iterations = 3, chunk_size = 50, overlap = 10, merge_strategy = "weighted_average" ) process_chunk(model, positions, coverage) result <- finalize(model) cat(sprintf("y[0]: %.4f\n", result$y[1])) ``` --- ## Best Practices for Genomic Data | Consideration | Recommendation | | --- | --- | | **Fraction** | 0.05–0.15 (preserve local features) | | **Iterations** | 3–5 (handle sequencing outliers) | | **Large data** | Use streaming mode | | **Sparse regions** | Use `boundary_policy="extend"` | | **Multiple chromosomes** | Process separately or ensure sorted | --- ## See Also - [Concepts](concepts.html) — How LOWESS works - `?Lowess` — All options - [Robustness](robustness.html) — Outlier downweighting in depth - [Merge Strategies](merge.html) — Streaming chunk reconciliation - [Boundary Handling](boundary.html) — Edge handling for sparse regions - [Real-Time Processing](use-case-real-time.html) — For sequencing runs ```{r session-info} sessionInfo() ```