GeneTrackR builds haplotypes directly from VCF sample genotypes and
keeps the complete analysis state in a HapVariant object.
The stable workflow is to define the biological interval once, construct
one canonical haplotype object, inspect the retained variants and
samples, and pass that same object to phenotype association, refinement,
and variant-effect analysis.
This article follows that object-centered workflow rather than rebuilding genotype matrices for each downstream task.
This article follows one continuous workflow:
HapVariant object and its core tables;The main example uses the designed GeneA locus. Its gene
body contains 11 variants and 36 complete samples that form four
balanced haplotypes with nine samples per haplotype.
Package documentation: https://renscq.github.io/GeneTrackR/.
After Bioconductor acceptance, install GeneTrackR with
BiocManager:
if (!requireNamespace("BiocManager", quietly = TRUE)) {
install.packages("BiocManager")
}
BiocManager::install("GeneTrackR")
library(GeneTrackR)The development version remains available from the GeneTrackR GitHub repository.
Locate and read the bundled demo files:
vcf_file <- system.file(
"extdata",
"gtr_demo_variants.vcf",
package = "GeneTrackR"
)
gp_file <- system.file(
"extdata",
"gtr_demo.genePredExt",
package = "GeneTrackR"
)
vcf <- read_vcf(
vcf_file,
mode = "memory",
keep_genotype = TRUE,
verbose = FALSE,
progress = FALSE
)
gp <- read_genepred(
gp_file,
format = "genePredExt",
verbose = FALSE,
progress = FALSE
)Haplotype construction requires VCF sample genotype columns. If a VCF
was previously read with keep_genotype = FALSE, read it
again with keep_genotype = TRUE before calling the
haplotype functions.
For indexed large VCF files, the input can also be a lazy
VariantTrack or a VCF file path. GeneTrackR retrieves only
the requested haplotype region before constructing the genotype
matrix.
For gene- or transcript-defined analysis, use
hap_gene_variant(). The primary GeneA workflow
intentionally uses the gene body only so that the
haplotype definition is based on variants inside the annotated
locus:
hap_gene <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
genotype_mode = "string"
)
#> [GeneTrackR] Retrieved variants: 11.
hap_gene
#> <HapVariant>
#> region : chr1:12340001-12352000
#> variants : 11
#> samples : 36
#> haplotypes: 4The demo is designed so that this call contains:
The four genotype patterns are intentionally hierarchical:
Hap1/Hap2 are the closest pair, Hap3/Hap4 are
the second closest pair, and cross-pair comparisons differ at many more
GeneA variants. This structure is used later by the phenotype-refinement
demo.
Check these values directly from the returned object rather than assuming a fixed number for real datasets:
hap_gene$meta
#> $genotype_mode
#> [1] "string"
#>
#> $missing_genotype
#> [1] NA
#>
#> $min_variant_number
#> [1] 11
#>
#> $sample_n
#> [1] 36
#>
#> $variant_n
#> [1] 11
#>
#> $haplotype_n
#> [1] 4
hap_gene$haplotypes[, c("hap_id", "sample_n", "samples"), with = FALSE]
#> Key: <hap_id>
#> hap_id sample_n samples
#> <char> <int> <char>
#> 1: Hap1 9 S10;S11;S12;S13;S14;S15;S16;S17;S18
#> 2: Hap2 9 S01;S02;S03;S04;S05;S06;S07;S08;S09
#> 3: Hap3 9 S19;S20;S21;S22;S23;S24;S25;S26;S27
#> 4: Hap4 9 S28;S29;S30;S31;S32;S33;S34;S35;S36hap_id is assigned from the observed genotype patterns
after grouping. Treat the genotype pattern and sample membership as the
biological result; do not assume that Hap1,
Hap2, and so on have the same biological meaning across
independently constructed regions.
A HapVariant keeps the complete state needed by
downstream GeneTrackR functions:
hap_gene$region
#> $locator
#> [1] "gene"
#>
#> $id
#> [1] "GeneA"
#>
#> $chrom
#> [1] "chr1"
#>
#> $start
#> [1] 12340001
#>
#> $end
#> [1] 12352000
#>
#> $core_start
#> [1] 12340001
#>
#> $core_end
#> [1] 12352000
#>
#> $upstream
#> [1] 0
#>
#> $downstream
#> [1] 0
#>
#> $strand
#> [1] "+"
#>
#> $strand_aware
#> [1] TRUE
hap_gene$variants
#> chrom pos variant_id ref alt qual filter
#> <char> <int> <char> <char> <char> <num> <char>
#> 1: chr1 12340250 varA01 A G 60 PASS
#> 2: chr1 12340600 varA02 T C 60 PASS
#> 3: chr1 12342550 varA03 C G 60 PASS
#> 4: chr1 12342620 varLD01 G A 60 PASS
#> 5: chr1 12342710 varLD02 A T 60 PASS
#> 6: chr1 12342805 varLD03 C T 60 PASS
#> 7: chr1 12342920 varLD04 G C 60 PASS
#> 8: chr1 12343040 varLD05 T G 60 PASS
#> 9: chr1 12343180 varLD06 A C 60 PASS
#> 10: chr1 12344500 varA04 A ATG 60 PASS
#> 11: chr1 12351050 varA05 ATG A 60 PASS
#> info FORMAT S01 S02 S03 S04
#> <char> <char> <char> <char> <char> <char>
#> 1: ROLE=core_haplotype,high_ld GT 0/0 0/0 0/0 0/0
#> 2: ROLE=core_haplotype GT 0/0 0/0 0/0 0/0
#> 3: ROLE=core_haplotype,protein_effect GT 0/0 0/0 0/0 0/0
#> 4: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0
#> 5: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0
#> 6: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0
#> 7: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0
#> 8: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0
#> 9: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0
#> 10: ROLE=core_haplotype,indel GT 0/0 0/0 0/0 0/0
#> 11: ROLE=core_haplotype,indel GT 0/0 0/0 0/0 0/0
#> S05 S06 S07 S08 S09 S10 S11 S12 S13 S14
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 2: 0/0 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1
#> 3: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 4: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 5: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 6: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 7: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 8: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 9: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 10: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 11: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> S15 S16 S17 S18 S19 S20 S21 S22 S23 S24
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 2: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 3: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 4: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 5: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 6: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 7: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 8: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 9: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 10: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1
#> 11: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> S25 S26 S27 S28 S29 S30 S31 S32 S33 S34
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 2: 1/1 1/1 1/1 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 3: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 4: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 5: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 6: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 7: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 8: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 9: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 10: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 11: 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> S35 S36 variant_type start end
#> <char> <char> <char> <int> <int>
#> 1: 1/1 1/1 SNP 12340250 12340250
#> 2: 0/0 0/0 SNP 12340600 12340600
#> 3: 1/1 1/1 SNP 12342550 12342550
#> 4: 1/1 1/1 SNP 12342620 12342620
#> 5: 1/1 1/1 SNP 12342710 12342710
#> 6: 1/1 1/1 SNP 12342805 12342805
#> 7: 1/1 1/1 SNP 12342920 12342920
#> 8: 1/1 1/1 SNP 12343040 12343040
#> 9: 1/1 1/1 SNP 12343180 12343180
#> 10: 1/1 1/1 INS 12344500 12344500
#> 11: 1/1 1/1 DEL 12351050 12351050
hap_gene$genotype_long
#> sample_id chrom pos variant_id ref alt variant_type genotype
#> <char> <char> <int> <char> <char> <char> <char> <char>
#> 1: S01 chr1 12340250 varA01 A G SNP A
#> 2: S01 chr1 12340600 varA02 T C SNP T
#> 3: S01 chr1 12342550 varA03 C G SNP C
#> 4: S01 chr1 12342620 varLD01 G A SNP G
#> 5: S01 chr1 12342710 varLD02 A T SNP A
#> ---
#> 392: S36 chr1 12342920 varLD04 G C SNP C
#> 393: S36 chr1 12343040 varLD05 T G SNP G
#> 394: S36 chr1 12343180 varLD06 A C SNP C
#> 395: S36 chr1 12344500 varA04 A ATG INS i3
#> 396: S36 chr1 12351050 varA05 ATG A DEL A
#> genotype_missing
#> <lgcl>
#> 1: FALSE
#> 2: FALSE
#> 3: FALSE
#> 4: FALSE
#> 5: FALSE
#> ---
#> 392: FALSE
#> 393: FALSE
#> 394: FALSE
#> 395: FALSE
#> 396: FALSE
hap_gene$genotype_wide
#> Key: <hap_pattern>
#> sample_id hap_id hap_pattern non_missing_variant_n varA01
#> <char> <char> <char> <int> <char>
#> 1: S10 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 2: S11 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 3: S12 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 4: S13 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 5: S14 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 6: S15 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 7: S16 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 8: S17 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 9: S18 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11 A
#> 10: S01 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 11: S02 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 12: S03 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 13: S04 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 14: S05 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 15: S06 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 16: S07 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 17: S08 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 18: S09 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11 A
#> 19: S19 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 20: S20 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 21: S21 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 22: S22 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 23: S23 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 24: S24 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 25: S25 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 26: S26 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 27: S27 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11 G
#> 28: S28 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 29: S29 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 30: S30 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 31: S31 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 32: S32 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 33: S33 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 34: S34 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 35: S35 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> 36: S36 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11 G
#> sample_id hap_id hap_pattern non_missing_variant_n varA01
#> <char> <char> <char> <int> <char>
#> varA02 varA03 varLD01 varLD02 varLD03 varLD04 varLD05 varLD06 varA04 varA05
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: C C G A C G T A A i3
#> 2: C C G A C G T A A i3
#> 3: C C G A C G T A A i3
#> 4: C C G A C G T A A i3
#> 5: C C G A C G T A A i3
#> 6: C C G A C G T A A i3
#> 7: C C G A C G T A A i3
#> 8: C C G A C G T A A i3
#> 9: C C G A C G T A A i3
#> 10: T C G A C G T A A i3
#> 11: T C G A C G T A A i3
#> 12: T C G A C G T A A i3
#> 13: T C G A C G T A A i3
#> 14: T C G A C G T A A i3
#> 15: T C G A C G T A A i3
#> 16: T C G A C G T A A i3
#> 17: T C G A C G T A A i3
#> 18: T C G A C G T A A i3
#> 19: C G A T T C G C i3 i3
#> 20: C G A T T C G C i3 i3
#> 21: C G A T T C G C i3 i3
#> 22: C G A T T C G C i3 i3
#> 23: C G A T T C G C i3 i3
#> 24: C G A T T C G C i3 i3
#> 25: C G A T T C G C i3 i3
#> 26: C G A T T C G C i3 i3
#> 27: C G A T T C G C i3 i3
#> 28: T G A T T C G C i3 A
#> 29: T G A T T C G C i3 A
#> 30: T G A T T C G C i3 A
#> 31: T G A T T C G C i3 A
#> 32: T G A T T C G C i3 A
#> 33: T G A T T C G C i3 A
#> 34: T G A T T C G C i3 A
#> 35: T G A T T C G C i3 A
#> 36: T G A T T C G C i3 A
#> varA02 varA03 varLD01 varLD02 varLD03 varLD04 varLD05 varLD06 varA04 varA05
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
hap_gene$haplotypes
#> Key: <hap_id>
#> hap_id sample_n samples varA01 varA02 varA03
#> <char> <int> <char> <char> <char> <char>
#> 1: Hap1 9 S10;S11;S12;S13;S14;S15;S16;S17;S18 A C C
#> 2: Hap2 9 S01;S02;S03;S04;S05;S06;S07;S08;S09 A T C
#> 3: Hap3 9 S19;S20;S21;S22;S23;S24;S25;S26;S27 G C G
#> 4: Hap4 9 S28;S29;S30;S31;S32;S33;S34;S35;S36 G T G
#> varLD01 varLD02 varLD03 varLD04 varLD05 varLD06 varA04 varA05
#> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: G A C G T A A i3
#> 2: G A C G T A A i3
#> 3: A T T C G C i3 i3
#> 4: A T T C G C i3 A
hap_gene$sample_haplotypes
#> Key: <hap_pattern>
#> sample_id hap_id hap_pattern non_missing_variant_n
#> <char> <char> <char> <int>
#> 1: S10 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 2: S11 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 3: S12 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 4: S13 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 5: S14 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 6: S15 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 7: S16 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 8: S17 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 9: S18 Hap1 A|C|C|G|A|C|G|T|A|A|i3 11
#> 10: S01 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 11: S02 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 12: S03 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 13: S04 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 14: S05 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 15: S06 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 16: S07 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 17: S08 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 18: S09 Hap2 A|T|C|G|A|C|G|T|A|A|i3 11
#> 19: S19 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 20: S20 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 21: S21 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 22: S22 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 23: S23 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 24: S24 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 25: S25 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 26: S26 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 27: S27 Hap3 G|C|G|A|T|T|C|G|C|i3|i3 11
#> 28: S28 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 29: S29 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 30: S30 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 31: S31 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 32: S32 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 33: S33 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 34: S34 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 35: S35 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> 36: S36 Hap4 G|T|G|A|T|T|C|G|C|i3|A 11
#> sample_id hap_id hap_pattern non_missing_variant_n
#> <char> <char> <char> <int>The components have distinct purposes:
| Component | Content | Typical use |
|---|---|---|
region |
locator, chromosome, boundaries, strand, and flank settings | confirm the biological interval |
variants |
retained VCF variant records | inspect variant order and REF/ALT alleles |
genotype_long |
one sample × variant genotype per row | detailed genotype inspection |
genotype_wide |
one sample per row with variant columns | inspect the full genotype matrix |
haplotypes |
one row per unique haplotype with sample counts | summarize haplotype groups |
sample_haplotypes |
sample-to-haplotype assignment | join with phenotype or other metadata |
The meta list records the genotype representation,
missing-value policy, retained sample number, variant number, and
haplotype number:
hap_gene$meta
#> $genotype_mode
#> [1] "string"
#>
#> $missing_genotype
#> [1] NA
#>
#> $min_variant_number
#> [1] 11
#>
#> $sample_n
#> [1] 36
#>
#> $variant_n
#> [1] 11
#>
#> $haplotype_n
#> [1] 4This object is already the canonical input for
plot_hap_variant(), plot_hap_pheno(),
refine_haplotype(), and plot_variant_effect().
There is no need to rebuild a genotype matrix manually.
GeneTrackR provides two genotype representations through
genotype_mode.
genotype_mode = "string" is recommended when the
haplotype table itself is important for interpretation:
hap_gene_string <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
genotype_mode = "string"
)
#> [GeneTrackR] Retrieved variants: 11.
hap_gene_string$haplotypes
#> Key: <hap_id>
#> hap_id sample_n samples varA01 varA02 varA03
#> <char> <int> <char> <char> <char> <char>
#> 1: Hap1 9 S10;S11;S12;S13;S14;S15;S16;S17;S18 A C C
#> 2: Hap2 9 S01;S02;S03;S04;S05;S06;S07;S08;S09 A T C
#> 3: Hap3 9 S19;S20;S21;S22;S23;S24;S25;S26;S27 G C G
#> 4: Hap4 9 S28;S29;S30;S31;S32;S33;S34;S35;S36 G T G
#> varLD01 varLD02 varLD03 varLD04 varLD05 varLD06 varA04 varA05
#> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: G A C G T A A i3
#> 2: G A C G T A A i3
#> 3: A T T C G C i3 i3
#> 4: A T T C G C i3 ASingle-base alleles are displayed directly as A,
T, C, or G. Longer REF/ALT
alleles are compressed to iN, where N is the
displayed allele length. The haplotype plot maps allele classes in the
stable order A, T, C,
G, and indel.
String mode is also a compact display representation rather than a
phased dosage representation: if a genotype contains an alternate
allele, GeneTrackR displays the first observed ALT allele label for that
variant. Inspect the original genotype columns in vcf$data
when zygosity, phase, or multi-allelic dosage must be retained
explicitly.
genotype_mode = "code" collapses each genotype to
reference versus alternate presence:
hap_gene_code <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
genotype_mode = "code"
)
#> [GeneTrackR] Retrieved variants: 11.
hap_gene_code$haplotypes
#> Key: <hap_id>
#> hap_id sample_n samples varA01 varA02 varA03
#> <char> <int> <char> <char> <char> <char>
#> 1: Hap1 9 S01;S02;S03;S04;S05;S06;S07;S08;S09 0 0 0
#> 2: Hap2 9 S10;S11;S12;S13;S14;S15;S16;S17;S18 0 1 0
#> 3: Hap3 9 S28;S29;S30;S31;S32;S33;S34;S35;S36 1 0 1
#> 4: Hap4 9 S19;S20;S21;S22;S23;S24;S25;S26;S27 1 1 1
#> varLD01 varLD02 varLD03 varLD04 varLD05 varLD06 varA04 varA05
#> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: 0 0 0 0 0 0 0 0
#> 2: 0 0 0 0 0 0 0 0
#> 3: 1 1 1 1 1 1 1 1
#> 4: 1 1 1 1 1 1 1 0In code mode:
0 means the genotype contains only the reference
allele;1 means at least one alternate allele is present.Therefore code mode is a binary REF/ALT-presence
representation, not allele dosage. A heterozygous genotype and
a homozygous alternate genotype both become 1. Use
allele-string mode when the displayed allele identity is more important
than compact binary grouping.
By default, min_variant_number = NULL requires a sample
to have non-missing genotypes at all retained variants.
This is the safest default for defining complete haplotypes.
The GeneA gene body has complete demo genotypes, so all 36 samples are retained:
Flanking regions can introduce additional variants with missing data.
The demo upstream variant varAup01 is intentionally
designed with missing/heterozygous genotypes. Adding it changes the
haplotype definition:
hap_gene_upstream <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
upstream = 500,
downstream = 0,
strand_aware = TRUE,
genotype_mode = "string"
)
#> [GeneTrackR] Retrieved variants: 12.
hap_gene_upstream$region
#> $locator
#> [1] "gene"
#>
#> $id
#> [1] "GeneA"
#>
#> $chrom
#> [1] "chr1"
#>
#> $start
#> [1] 12339501
#>
#> $end
#> [1] 12352000
#>
#> $core_start
#> [1] 12340001
#>
#> $core_end
#> [1] 12352000
#>
#> $upstream
#> [1] 500
#>
#> $downstream
#> [1] 0
#>
#> $strand
#> [1] "+"
#>
#> $strand_aware
#> [1] TRUE
hap_gene_upstream$meta
#> $genotype_mode
#> [1] "string"
#>
#> $missing_genotype
#> [1] NA
#>
#> $min_variant_number
#> [1] 12
#>
#> $sample_n
#> [1] 32
#>
#> $variant_n
#> [1] 12
#>
#> $haplotype_n
#> [1] 6To retain samples that are missing a limited number of variants, set
an explicit threshold. The extended demo region contains 12 variants, so
min_variant_number = 11 allows one missing genotype:
hap_gene_upstream_relaxed <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
upstream = 500,
genotype_mode = "string",
min_variant_number = 11
)
#> [GeneTrackR] Retrieved variants: 12.
hap_gene_upstream_relaxed$sample_haplotypes
#> Key: <hap_pattern>
#> sample_id hap_id hap_pattern non_missing_variant_n
#> <char> <char> <char> <int>
#> 1: S10 Hap3 A|A|C|C|G|A|C|G|T|A|A|i3 12
#> 2: S11 Hap3 A|A|C|C|G|A|C|G|T|A|A|i3 12
#> 3: S13 Hap3 A|A|C|C|G|A|C|G|T|A|A|i3 12
#> 4: S15 Hap3 A|A|C|C|G|A|C|G|T|A|A|i3 12
#> 5: S16 Hap3 A|A|C|C|G|A|C|G|T|A|A|i3 12
#> 6: S17 Hap3 A|A|C|C|G|A|C|G|T|A|A|i3 12
#> 7: S18 Hap3 A|A|C|C|G|A|C|G|T|A|A|i3 12
#> 8: S01 Hap4 A|A|T|C|G|A|C|G|T|A|A|i3 12
#> 9: S02 Hap4 A|A|T|C|G|A|C|G|T|A|A|i3 12
#> 10: S04 Hap4 A|A|T|C|G|A|C|G|T|A|A|i3 12
#> 11: S06 Hap4 A|A|T|C|G|A|C|G|T|A|A|i3 12
#> 12: S07 Hap4 A|A|T|C|G|A|C|G|T|A|A|i3 12
#> 13: S08 Hap4 A|A|T|C|G|A|C|G|T|A|A|i3 12
#> 14: S09 Hap4 A|A|T|C|G|A|C|G|T|A|A|i3 12
#> 15: S12 Hap5 NA|A|C|C|G|A|C|G|T|A|A|i3 11
#> 16: S03 Hap6 NA|A|T|C|G|A|C|G|T|A|A|i3 11
#> 17: S21 Hap7 NA|G|C|G|A|T|T|C|G|C|i3|i3 11
#> 18: S30 Hap8 NA|G|T|G|A|T|T|C|G|C|i3|A 11
#> 19: S14 Hap9 T|A|C|C|G|A|C|G|T|A|A|i3 12
#> 20: S05 Hap10 T|A|T|C|G|A|C|G|T|A|A|i3 12
#> 21: S19 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 22: S20 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 23: S22 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 24: S23 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 25: S24 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 26: S25 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 27: S26 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 28: S27 Hap1 T|G|C|G|A|T|T|C|G|C|i3|i3 12
#> 29: S28 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> 30: S29 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> 31: S31 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> 32: S32 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> 33: S33 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> 34: S34 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> 35: S35 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> 36: S36 Hap2 T|G|T|G|A|T|T|C|G|C|i3|A 12
#> sample_id hap_id hap_pattern non_missing_variant_n
#> <char> <char> <char> <int>Use relaxed thresholds deliberately. Missing values become part of
the observed haplotype pattern and may create additional haplotype
groups. For the main GeneA tutorial, the unextended gene-body object
hap_gene remains the recommended analysis object.
A custom missing label can be supplied for display:
hap_missing_label <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
upstream = 500,
genotype_mode = "code",
missing_genotype = "-",
min_variant_number = 11
)
#> [GeneTrackR] Retrieved variants: 12.Internally, GeneTrackR still tracks which genotypes are biologically missing, so a custom display label does not convert missing values into valid genotype calls.
Use transcript_id instead of gene_id when
variants should be restricted to one transcript locus:
hap_tx <- hap_gene_variant(
vcf = vcf,
annotation = gp,
transcript_id = "TxA1",
genotype_mode = "string"
)
#> [GeneTrackR] Retrieved variants: 11.
hap_tx$region
#> $locator
#> [1] "transcript"
#>
#> $id
#> [1] "TxA1"
#>
#> $chrom
#> [1] "chr1"
#>
#> $start
#> [1] 12340001
#>
#> $end
#> [1] 12352000
#>
#> $core_start
#> [1] 12340001
#>
#> $core_end
#> [1] 12352000
#>
#> $upstream
#> [1] 0
#>
#> $downstream
#> [1] 0
#>
#> $strand
#> [1] "+"
#>
#> $strand_aware
#> [1] TRUESupply exactly one of gene_id or
transcript_id.
upstream and downstream are interpreted
relative to transcription direction when
strand_aware = TRUE:
hap_gene_flank <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
upstream = 1000,
downstream = 500,
strand_aware = TRUE,
genotype_mode = "string",
min_variant_number = 1
)
#> [GeneTrackR] Retrieved variants: 13.
hap_gene_flank$region
#> $locator
#> [1] "gene"
#>
#> $id
#> [1] "GeneA"
#>
#> $chrom
#> [1] "chr1"
#>
#> $start
#> [1] 12339001
#>
#> $end
#> [1] 12352500
#>
#> $core_start
#> [1] 12340001
#>
#> $core_end
#> [1] 12352000
#>
#> $upstream
#> [1] 1000
#>
#> $downstream
#> [1] 500
#>
#> $strand
#> [1] "+"
#>
#> $strand_aware
#> [1] TRUEFor a negative-strand gene, biological upstream is toward increasing
genomic coordinates. GeneTrackR handles this reversal automatically when
strand_aware = TRUE.
Use hap_region_variant() when the interval is defined
directly rather than by annotation:
hap_region <- hap_region_variant(
vcf = vcf,
chrom = "chr1",
start = 12340001,
end = 12352000,
genotype_mode = "code"
)
#> [GeneTrackR] Retrieved variants: 11.
hap_region
#> <HapVariant>
#> region : chr1:12340001-12352000
#> variants : 11
#> samples : 36
#> haplotypes: 4This is useful for GWAS/LD intervals, promoter windows, QTL regions, or any custom locus that does not correspond exactly to one annotated gene or transcript.
The haplotype can be restricted before grouping. For example, analyze a subset of samples:
hap_sample_subset <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
samples = sprintf("S%02d", 1:18),
genotype_mode = "string"
)
#> [GeneTrackR] Retrieved variants: 11.
hap_sample_subset$meta
#> $genotype_mode
#> [1] "string"
#>
#> $missing_genotype
#> [1] NA
#>
#> $min_variant_number
#> [1] 11
#>
#> $sample_n
#> [1] 18
#>
#> $variant_n
#> [1] 11
#>
#> $haplotype_n
#> [1] 2Or construct haplotypes using only SNPs:
hap_snp <- hap_gene_variant(
vcf = vcf,
annotation = gp,
gene_id = "GeneA",
variant_type = "SNP",
genotype_mode = "string"
)
#> [GeneTrackR] Retrieved variants: 9.
hap_snp$variants
#> chrom pos variant_id ref alt qual filter
#> <char> <int> <char> <char> <char> <num> <char>
#> 1: chr1 12340250 varA01 A G 60 PASS
#> 2: chr1 12340600 varA02 T C 60 PASS
#> 3: chr1 12342550 varA03 C G 60 PASS
#> 4: chr1 12342620 varLD01 G A 60 PASS
#> 5: chr1 12342710 varLD02 A T 60 PASS
#> 6: chr1 12342805 varLD03 C T 60 PASS
#> 7: chr1 12342920 varLD04 G C 60 PASS
#> 8: chr1 12343040 varLD05 T G 60 PASS
#> 9: chr1 12343180 varLD06 A C 60 PASS
#> info FORMAT S01 S02 S03 S04 S05
#> <char> <char> <char> <char> <char> <char> <char>
#> 1: ROLE=core_haplotype,high_ld GT 0/0 0/0 0/0 0/0 0/0
#> 2: ROLE=core_haplotype GT 0/0 0/0 0/0 0/0 0/0
#> 3: ROLE=core_haplotype,protein_effect GT 0/0 0/0 0/0 0/0 0/0
#> 4: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0 0/0
#> 5: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0 0/0
#> 6: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0 0/0
#> 7: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0 0/0
#> 8: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0 0/0
#> 9: ROLE=high_ld,ld_gradient GT 0/0 0/0 0/0 0/0 0/0
#> S06 S07 S08 S09 S10 S11 S12 S13 S14 S15 S16
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 2: 0/0 0/0 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 3: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 4: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 5: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 6: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 7: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 8: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> 9: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
#> S17 S18 S19 S20 S21 S22 S23 S24 S25 S26 S27
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 2: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 3: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 4: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 5: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 6: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 7: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 8: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> 9: 0/0 0/0 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1
#> S28 S29 S30 S31 S32 S33 S34 S35 S36 variant_type
#> <char> <char> <char> <char> <char> <char> <char> <char> <char> <char>
#> 1: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> 2: 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 SNP
#> 3: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> 4: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> 5: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> 6: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> 7: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> 8: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> 9: 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 1/1 SNP
#> start end
#> <int> <int>
#> 1: 12340250 12340250
#> 2: 12340600 12340600
#> 3: 12342550 12342550
#> 4: 12342620 12342620
#> 5: 12342710 12342710
#> 6: 12342805 12342805
#> 7: 12342920 12342920
#> 8: 12343040 12343040
#> 9: 12343180 12343180Filtering variants changes the haplotype definition and may merge
previously distinct haplotypes. Always inspect haplotypes
and sample_haplotypes after changing the retained variant
set.
hap_variant() remains available as a compatibility
wrapper, but new code should prefer hap_gene_variant() for
gene/transcript queries and hap_region_variant() for direct
genomic intervals.
plot_hap_variant() combines the gene model,
natural-variant markers, connector lines, REF/ALT reference rows, and
haplotype genotype table:
hap_variant_figure <- plot_hap_variant(
hap_gene,
annotation = gp,
min_hap_samples = 3,
show_reference_row = TRUE,
variant_label = "pos",
gene_pos_x_angle = 90,
gene_track_legend_position = "top",
direction_mode = "gene",
table_x_angle = 90,
text_size = 9
)
hap_variant_figureGeneral plotting palettes default to Paired;
plot_ld_block() is the deliberate package-level exception
and defaults to Reds. The main haplotype visual controls
can still be changed independently:
hap_variant_custom <- plot_hap_variant(
hap_gene,
annotation = gp,
min_hap_samples = 3,
show_reference_row = TRUE,
gene_palette = "Paired",
table_palette = "Paired",
variant_palette = "Paired",
table_alpha = 0.7,
variant_alpha = 0.8,
genotype_text_size = 3,
variant_marker_size = 3,
gene_track_height = 1.4,
connector_height = 0.4,
text_size = 9
)
hap_variant_customFor allele-string haplotypes, table colors always follow the stable
biological class order A, T, C,
G, and indel. Custom colors can be supplied
explicitly with those names:
plot_hap_variant(
hap_gene,
annotation = gp,
min_hap_samples = 3,
table_colors = c(
A = "#1B9E77",
T = "#D95F02",
C = "#7570B3",
G = "#E7298A",
indel = "#66A61E"
),
text_size = 9
)Use show_variant_marker = FALSE to hide natural-variant
triangles, or adjust variant_marker_size when the locus
contains many variants.
Do not reconstruct haplotypes separately for each downstream
analysis. The hap_gene object created in Step 2 is the
input for the following modules:
# Haplotype-phenotype association
# hap_res <- plot_hap_pheno(
# hap_gene,
# phenotype = pheno,
# traits = "seed_weight",
# min_hap_samples = 3
# )
# Phenotype-guided refinement
# refined <- refine_haplotype(
# hap_gene,
# phenotype = pheno,
# traits = "seed_weight",
# min_hap_samples = 3
# )
# Variant-effect prioritization
# effect <- plot_variant_effect(
# hap_gene,
# phenotype = pheno,
# traits = "protein_content",
# min_group_samples = 3
# )Keeping one well-defined HapVariant as the common input
ensures that the variant set, sample set, missing-data rule, and
haplotype assignment remain consistent across visualization, phenotype
association, refinement, and variant-effect analysis.
sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] GeneTrackR_0.99.2 rmarkdown_2.32
#>
#> loaded via a namespace (and not attached):
#> [1] gtable_0.3.6 jsonlite_2.0.0 crayon_1.5.3
#> [4] compiler_4.6.1 zip_3.0.2 Rcpp_1.1.2
#> [7] Biostrings_2.81.9 bitops_1.1-0 Rsamtools_2.29.0
#> [10] GenomicRanges_1.65.4 parallel_4.6.1 jquerylib_0.1.4
#> [13] IRanges_2.47.5 Seqinfo_1.3.2 scales_1.4.0
#> [16] BiocParallel_1.47.0 yaml_2.3.12 fastmap_1.2.0
#> [19] XVector_0.53.0 ggplot2_4.0.3 R6_2.6.1
#> [22] patchwork_1.3.2 labeling_0.4.3 generics_0.1.4
#> [25] openxlsx_4.2.9 knitr_1.52 BiocGenerics_0.59.12
#> [28] maketools_1.3.2 bslib_0.12.0 RColorBrewer_1.1-3
#> [31] rlang_1.3.0 stringi_1.8.9 cachem_1.1.0
#> [34] xfun_0.61 sass_0.4.10 sys_3.4.3
#> [37] S7_0.2.2 otel_0.2.0 cli_3.6.6
#> [40] withr_3.0.3 digest_0.6.39 grid_4.6.1
#> [43] lifecycle_1.0.5 S4Vectors_0.51.10 vctrs_0.7.3
#> [46] evaluate_1.0.5 glue_1.8.1 data.table_1.18.6.1
#> [49] farver_2.1.2 codetools_0.2-20 buildtools_1.0.0
#> [52] stats4_4.6.1 tools_4.6.1 htmltools_0.5.9