smartpca: columns of SNP weight matrix are not orthogonal with ldregress on
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 207
- Forks
- 61
- PR merge metrics
- No merged PRs in 30d
Description
While trying to integrate smartpca output with the R package bigsnpr, I've found that when ldregress mode is on, the snpweightoutname matrix columns are pretty far from being orthogonal -- the values off the diagonal of the cross product are much farther from zero than I'd expect from rounding and floating point errors. (I'm not a real mathsy guy, so I hope I'm using the terminology correctly and not missing anything too obvious.)
From a run calculating 10 PCs on 521616 SNPs x 12782 samples and ldregress: 200, loading the snpweightoutname file into R:
library(dplyr)
snpweight <- read.table(snpweight_file, stringsAsFactors = F)
snpweight_rescaled <- snpweight %>%
select(-(1:3)) %>%
sapply(function(x) x / sqrt(sum(x ^ 2))
crossprod(snpweight_rescaled)
# V4 V5 V6 V7 V8
# V4 1.0000000000 0.0629886216 -0.0551280009 0.0342755900 -3.184831e-02 ...
# V5 0.0629886216 1.0000000000 -0.0754935467 0.0663489089 -3.037471e-02 ...
# V6 -0.0551280009 -0.0754935467 1.0000000000 -0.0308700444 1.562871e-02 ...
# V7 0.0342755900 0.0663489089 -0.0308700444 1.0000000000 1.967471e-03 ...
# V8 -0.0318483056 -0.0303747146 0.0156287070 0.0019674706 1.000000e+00 ...
# V9 0.0015981099 -0.0198431477 -0.0225956002 -0.0077647879 -1.527105e-02 ...
# V10 0.0029581338 0.0164261311 0.0014516901 -0.0007959342 -3.126125e-05 ...
# V11 0.0006888677 -0.0002119814 -0.0070838543 0.0003065091 1.261866e-03 ...
# V12 0.0008047758 -0.0009930216 -0.0016761682 0.0006491613 -2.979100e-03 ...
# V13 -0.0005483224 0.0015044037 -0.0008509219 0.0047795698 4.093559e-04 ...
But on the exact same run as above except with ldregress off ("vanilla" mode), the cross product is basically identity, off by about as much as you'd expect given that the SNP weights are rounded to 3 dp:
vanilla_snpweight <- read.table(vanilla_snpweight_file, stringsAsFactors = F)
vanilla_snpweight_rescaled <- vanilla_snpweight %>%
select(-(1:3)) %>%
sapply(function(x) x / sqrt(sum(x ^ 2))
crossprod(vanilla_snpweight_rescaled)
# V4 V5 V6 V7 V8
# V4 1.000000e+00 -4.875293e-07 6.548305e-08 -4.504985e-07 4.295304e-07 ...
# V5 -4.875293e-07 1.000000e+00 -1.206785e-06 -2.307409e-07 -1.165748e-06 ...
# V6 6.548305e-08 -1.206785e-06 1.000000e+00 -4.188756e-07 -6.649852e-07 ...
# V7 -4.504985e-07 -2.307409e-07 -4.188756e-07 1.000000e+00 -4.656665e-07 ...
# V8 4.295304e-07 -1.165748e-06 -6.649852e-07 -4.656665e-07 1.000000e+00 ...
# V9 -1.534980e-07 -2.369042e-07 -1.517975e-07 2.652259e-07 2.653215e-07 ...
# V10 -3.775631e-07 1.127952e-06 -1.817513e-06 2.046219e-07 1.711181e-07 ...
# V11 1.740131e-07 9.267356e-08 -2.228536e-07 -1.769993e-06 -4.598688e-07 ...
# V12 -3.790950e-07 -1.005894e-07 1.198180e-07 2.694341e-07 3.500083e-07 ...
# V13 3.474165e-07 2.574883e-08 4.890360e-07 -4.279933e-07 -3.077147e-07 ...
I also observe this in a different, smaller dataset, and also when I just set ldregress: 1.
Is this a bug or (more likely) am I just being dumb? Would there be any way of transforming the SNP weights matrix to one with orthogonal columns?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reported smartpca run with ldregress enabled and disabled, then compare the snpweightoutname matrices and their cross products. Trace the ldregress path responsible for producing the SNP weights; done means establishing whether the non-orthogonality is expected or correcting it and verifying the resulting output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, r
- Domain
- data
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100