QTLtools-trans(1)

✨ QTLtools-trans(1) ✨

Bioinformatics tools πŸ§šπŸ’œ


✨ NAME ✨

okay bestie, the name says it all 🫢 QTLtools trans - trans QTL analysis is the mode that hunts for trans (distal) QTLs, the ones that sneakily affect your phenotypes from far away πŸ¦‹


✨ SYNOPSIS ✨

QTLtools trans --vcf [in.vcf|in.vcf.gz|in.bcf|in.bed.gz] --bed
quantifications.bed.gz [--nominal | --permute | --sample integer |
--adjust in.txt] --out output.txt [OPTIONS]

✨ DESCRIPTION ✨

this mode maps trans (distal) QTLs πŸ’– using linear regression, and the whole method is written up in <https://www.nature.com/articles/ncomms15452>. the flow is giving clean: first it regresses out your covariates from the phenotype data, then it runs the linear regression between the phenotype residuals and the genotype. and if you pass --normal and --cov together, the residuals after covariate correction get rank normal transformed 🌈 it also comes with an efficient permutation scheme, so you can pick your pass:

  • a nominal pass (--nominal) that lists every genotype-phenotype association under a threshold you choose πŸ”₯
  • a permutation pass (--permute or --sample no_genes_to_sample) to empirically characterise the null distribution of associations πŸ§ͺ
  • an adjustment of the nominal p-values based on permutations (--adjust) πŸ‘‘

okay so the full permutation scheme (--permute) is the one that's literally the gold standard πŸ₯‡ all phenotypes get permuted together using the same random number sequence, which keeps the correlation structure intact. that means the only association actually broken in the data is the one between genotype and phenotype. then it runs a standard association scan that's identical to the one in the nominal pass. in practice this gets repeated for 100 permutations of the phenotype data πŸ’…

then comes FDR correction. you rank all the nominal p-values in ascending order and count how many p-values in the permuted data sets are smaller. that gives you an FDR estimate! for example, if there are 500 p-values in the permuted data sets that are smaller than the 100th smallest nominal p-value, you can assume the FDR for those first 100 associations is around 5% (=500/(100 Γ— 100)) ✨


now the approximation 🧚 this one exists for fast screening in trans, and it's built on what we already do in cis. the trick is assuming the phenotypes are independent and normally distributed (which you can enforce with --normal). since all the phenotypes are normally distributed, they're effectively the same, and the cis region removed from each phenotype is so small compared to the rest of the genome that its phenotype-specific impact is negligible. so the number of variants and the correlation amongst them is roughly the same for each phenotype, and each phenotype is roughly the same too 🫢 that means you can run permutations with a small number of phenotypes instead of all of them. this drastically cuts the computational burden, and the null distribution you generate can be applied to all phenotypes. πŸ”₯

here's how it works: it draws from the null by permuting some randomly chosen phenotypes, testing for associations with all variants in trans, and storing the smallest p-value. repeat this many times (typically 1000) and you've built a null distribution of the strongest associations for a single phenotype. then it gets made continuous by fitting a beta distribution, just like in cis, and that's used to adjust every nominal p-value from the initial pass for the number of variants being tested. to correct for the number of phenotypes tested, FDR gets estimated the same way as in cis, from the best adjusted p-values per phenotype (one per phenotype). this also gives an adjusted p-value threshold you can use to find all the phenotype-variant pairs that are whole-genome significant. the devs tested this and it gave similar results to the full permutation scheme, both in FDR estimates and number of discoveries, while running faster ⚑


πŸ’€ important: linear regressions assume normally distributed data, so the devs highly recommend using --normal to rank normal transform the phenotype quantifications. this helps you avoid false positive associations caused by outliers. and if you're using the approximate permutation scheme (--sample), you MUST use --normal or make sure your phenotypes are already normally distributed. no skipping this one, periodt πŸ™ˆ

✨ OPTIONS ✨

  • --vcf [in.vcf|in.bcf|in.vcf.gz|in.bed.gz] β€” genotypes in VCF/BCF format, or another molecular phenotype in BED format 🧬 if a variant has a DS field in its genotype FORMAT (the dosage calculated from genotype probabilities, like after imputation), that's what gets used as the genotype. if there's only a GT field in the genotype FORMAT, that's used instead and gets converted to a dosage. REQUIRED. πŸ’–
  • --bed quantifications.bed.gz β€” molecular phenotype quantifications in BED format. REQUIRED. 🌸
  • --out output.txt β€” where your output file goes. REQUIRED. πŸ“
  • --cov covariates.txt β€” the covariates you want to correct the phenotype data with. 🧹
  • --normal β€” rank normal transforms the phenotype data so each phenotype comes out normally distributed. RECOMMENDED. 🌈
  • --window integer β€” the size of the cis window flanking each phenotype's start position that gets removed. DEFAULT=5000000 πŸͺŸ
  • --threshold float β€” the p-value threshold below which hits get reported. give 1.0 if you want literally everything, but heads up, that might make a huge file 😭 when --adjust is provided, this threshold applies to the adjusted p-values instead. DEFAULT=1e-5 🎯
  • --bins integer β€” how many bins to use for categorising all p-values above --threshold. DEFAULT=1000 πŸ—‚οΈ
  • --nominal β€” calculates the nominal p-value for the genotype-phenotype associations and prints out the ones that pass your threshold. Mutually exclusive with --permute, --sample and --adjust. 🚫
  • --permute β€” permutes all phenotypes together, once. for multiple permutations you need to change the random seed with --seed each time. Mutually exclusive with --nominal, --sample and --adjust. πŸ”€
  • --sample integer β€” permutes randomly chosen phenotypes integer times. Mutually exclusive with --nominal, --permute, --adjust, and --chunk. 🎲
  • --adjust filename β€” tests and adjusts p-values using the null distribution in filename. Mutually exclusive with --nominal, --permute, and --sample. πŸ‘‘
  • --chunk integer1 integer2 β€” for parallelisation 🧩 it divides the data into integer2 chunks and processes chunk number integer1. the minimum number of chunks has to be at least the same as the number of chromosomes in the --bed file. πŸƒβ€β™€οΈ

✨ OUTPUT FILES ✨

these are all space separated, so grab your files and get to work πŸ“‚

🌸 .hits.txt.gz

this one details the variant-phenotype pairs that pass the threshold, with these columns:

  • 1 β€” the phenotype ID
  • 2 β€” the phenotype chromosome
  • 3 β€” start position of the phenotype
  • 4 β€” the variant ID
  • 5 β€” the variant chromosome
  • 6 β€” the start position of the variant
  • 7 β€” the nominal p-value of the association between the variant and the phenotype.
  • 8 β€” the adjusted p-value of the association between the variant and the phenotype. Requires --adjust
  • 9 β€” correlation coefficient

πŸ‘‘ .best.txt.gz

this one lists the most significant variant per phenotype, with these columns:

  • 1 β€” the phenotype ID
  • 2 β€” the adjusted p-value of the association between the variant and the phenotype. Requires --adjust
  • 3 β€” the nominal p-value of the association between the variant and the phenotype.
  • 4 β€” the variant ID

🫧 .bins.txt.gz

this one holds the binning of all hits with a p-value below your specified --threshold, with these columns:

  • 1 β€” the index of the bin
  • 2 β€” the lower bound of the correlation coefficient for this bin
  • 3 β€” the upper bound of the correlation coefficient for this bin
  • 4 β€” the upper bound of the p-value for this bin
  • 5 β€” the lower bound of the p-value for this bin

✨ FULL PERMUTATION ANALYSIS EXAMPLE ✨

  1. run a nominal analysis, rank normal transforming the phenotypes and outputting all associations with a p-value below 1e-5 πŸ”₯
QTLtools trans --vcf genotypes.chr22.vcf.gz --bed
genes.simulated.chr22.bed.gz --nominal --normal --out trans.nominal
  1. run a full permutation analysis with 100 jobs on a compute cluster πŸ–₯️ run the following, and make sure you change the seed for each permutation iteration. qsub needs to be swapped out for whatever job submission system you use (bsub, psub, etc...) πŸ’…
for j in $(seq 1 100); do
    echo "QTLtools trans --vcf genotypes.chr22.vcf.gz --bed
    genes.simulated.chr22.bed.gz --permute --normal --out
    trans.perm$j.txt --seed $j" | qsub
done

✨ APPROXIMATE PERMUTATION ANALYSIS EXAMPLE ✨

  1. build the null distribution by randomly selecting 1000 phenotypes, and rank normal transforming the phenotypes 🎲
QTLtools trans --vcf genotypes.chr22.vcf.gz --bed
genes.simulated.chr22.bed.gz --sample 1000 --normal --out trans.sample
  1. run the nominal pass, adjusting the p-values with the given null distribution, rank normal transforming the phenotypes, and printing out associations with an adjusted p-value less than 0.1 ✨
QTLtools trans --vcf genotypes.chr22.vcf.gz --bed
genes.simulated.chr22.bed.gz --adjust trans.sample.best.txt.gz
--threshold 0.1 --normal --out trans.adjust

✨ SEE ALSO ✨


✨ BUGS ✨

  • πŸ› versions up to and including 1.2 suffer from a bug in reading missing genotypes in VCF/BCF files. this bug affects variants that have a DS field in their genotype's FORMAT and have a missing genotype (DS field is .) in one of the samples. when that happens, the genotypes for all the samples get set to missing, which effectively removes that variant from the analyses 😭

please submit bugs to <https://github.com/qtltools/qtltools> πŸ’Œ


✨ CITATION ✨

Delaneau, O., Ongen, H., Brown, A. et al. A complete tool set for molecular QTL discovery and analysis. Nat Commun 8, 15452 (2017). <https://doi.org/10.1038/ncomms15452> πŸ“š


✨ AUTHORS ✨

Halit Ongen (halitongen@gmail.com), Olivier Delaneau (olivier.delaneau@gmail.com) πŸ‘©β€πŸ’»πŸ§‘β€πŸ’»


🫢 bestie, that's the whole tea. this page was brought to you by QTLtools v1.3, dated 06 May 2020, and filed under QTLtools-trans(1) πŸ’–βœ¨πŸ¦‹