<p>I received genome-wide association (GWAS) data from a colleague who's supposedly done all the imputation and quality control according to the consortium's standards. Genotyping was Illumina 660, imputed to HapMap (3.2 million SNPs total).</p>

<p>The data came to me as a matrix of 11,000 samples (rows) and 3.2 million SNPs (columns). There's a header row for each SNP, and genotypes are coded as the number of minor alleles (or allele dosage for imputed SNPs). </p>

<p>Here's a few rows and columns to show you what it looks like:</p>

<pre><code>rs1793851 rs9929479 rs929483
      2.0         0        1
      1.6         0        1
      2.0         NA       0
      2.0         0        1
      1.6         0        0
      2.0         1        NA
      1.0         0        0
      1.9         0        2
</code></pre>

<p>I've always used PLINK for GWAS data management, QC, and analysis because of its efficient data handling capabilities for GWAS data. However, this kind of data can't be imported directly into PLINK or converted into a pedigree format file. (<a href='http://pngu.mgh.harvard.edu/~purcell/plink/dosage.shtml'>PLINK does handle imputed data</a>, and so does <a href='http://www.stats.ox.ac.uk/~marchini/software/gwas/snptest.html'>SNPTEST</a>, but both of these require genotype probabilities and I only have the expected allele dosage).</p>

<p>I did write some R code to read in the data in chunks and run some simple summary and association statistics, but this is clunky and suboptimal for many reasons:</p>

<ol>
<li>The dataset first has to be split up (<a href='http://stackoverflow.com/questions/5265839/split-delimited-file-into-smaller-files-by-column'>I used a perl wrapper around UNIX/cut to do this</a>). After splitting the dataset into several hundred files with all my samples and a subset of SNPs, computing sample-level measures (sample call rate, relatedness, ethnic outliers) is going to be a real coding nightmare.</li>
<li>Subsetting analyses is going to be difficult (not as easy as PLINK's --exclude, --include, --keep, --remove, --cluster, etc).</li>
<li>PLINK integrates SNP annotation info (in the map file) to your results. Joining QC and analysis results to genomic position, minor allele, etc, will require lots of SQL joins.</li>
</ol>

<p>Ideally I don't want to rewrite software for GWAS data management, QC, and analysis. I've considered (1) analyzing only genotyped SNPS, or (2) rounding the allele dosage to the nearest integer so I can use PLINK, but both of these methods discard useful data.</p>

<p>Does anyone have any suggestions on how I should start to QC and analyze this data without re-inventing the wheel or rewriting PLINK? Any other software suggestions that could take this kind of data? Keep in mind, my dataset is nearly 100GB.</p>

<p>Thanks in advance.</p>

<p>For imputation, the primary QC really should be done on the input genotypes, rather than directly on the imputations.  Prior to imputation, I remove SNPs at MAF &lt; 0.01, HWE &lt; 1e-06, and only used SNPs present on 97% of the samples. Also, since Illumina data has relatively few A/T and G/C SNPs, I also remove those, as it completely removes any potential strand issues (most of my runs are meta-analyzed with other studies, so I think this step is worthwhile). In my opinion, these steps are a key part of good imputations.</p>

<p>However, you already have imputations, so I will assume that they are to high quality. The exact answer to your question depends on the software used for imputation.  Personally, I use MACH for most of my imputation work, and I use <a href='http://www.genabel.org/packages/ProbABEL'>ProbABEL</a> for association analysis. ProbABEL reads the MACH files directly without modification.  Also MACH2QTL and MACH2DAT can be used similarly, but I don't have any experience with those. In the analysis, ProbABEL does track the Imputation Quality score from the input files, and typically those are filtered at R2&lt;0.3, but that is typically done as part of the meta-analysis.</p>

<p>Some points:</p>

<ul>
<li>ProbABEL reads the entire file into memory, which will be sizable for large chromosomes and sample size.</li>
<li>The newer versions of ProbABEL have support for a "filevector" format which gets around these issue.  I've just started experimenting with this, and it will remove the memory issues I just mentioned. If the documentation is unclear, there is a better explanation <a href='http://forum.genabel.org/viewtopic.php?f=6&amp;t=22'>here</a> on how to use the files. The "filevector" format needs to be made via the <code>mach2databel</code> function of <a href='http://cran.r-project.org/web/packages/GenABEL/index.html'>GenABEL</a>.</li>
<li>To get this all to work, I have a custom job script written in Perl to queue the jobs, and I usually do several in parallel via the <a href='http://search.cpan.org/~dlux/Parallel-ForkManager-0.7.9/lib/Parallel/ForkManager.pm'>Parallel::Forkmanager</a> module, but you should choose your own poison.</li>
<li>ProbABEL can't take compressed files as input, which is not optimal, because the uncompressed files are huge. MACH2QTL and MACH2DAT can take compressed files, but I've still not jumped to that.</li>
<li>If your impuations came from IMPUTE, <a href='http://www.stats.ox.ac.uk/~marchini/software/gwas/snptest.html'>SNPTEST</a> can take the input directly, but I have no experience with SNPTEST.</li>
<li>The GenABEL package also has a <code>impute2databel</code> function to make filevector format for use with ProbABEL. I've not worked with this.</li>
<li>Previous answers cited association software for use with Beagle imputations. I have no experience with that myself.</li>
<li>These softwares typically allow for fairly standard association models, and if you want "unsupported" models, the work arounds are much slower. I've loaded all my genotypes into netcdf files and work via R with the <a href='http://cirrus.ucsd.edu/~pierce/ncdf/'>ncdf</a> library.</li>
<li>I don't recommend working with the "rounded" genotypes, as the decimal values appropriately capture uncertainty in the imputations.</li>
<li>You don't want to read the unrounded genotypes into R, as R does not support floats. Everything is read as double, and memory quickly becomes an issue. That is the reason for the netcdf workaround.</li>
</ul>

<p>Hopefully, this gives you some insight.</p>
