<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  
  <title>Digital Notebook - Vince Buffalo</title>
  <link href="http://vincebuffalo.org/feed/" rel="self"/>
  <li></li>href="http://vincebuffalo.org/"/>
  <updated>2012-03-31T15:53:48-07:00</updated>
  <id>http://vincebuffalo.org/</id>
  <author>
    <name>Digital Notebook</name>
    <email>vsbuffaloAAAA@gmail.com</email>
  </author>
  
  
  

  <entry>
    <title>Why I am I growing worried about reproducibility?</title>
    <link href="http://vincebuffalo.org/esasys/2012/03/25/reproducibility.html"/>
    <updated>2012-03-25T00:00:00-07:00</updated>
    <id>http://vincebuffalo.org/esasys/2012/03/25/reproducibility</id>
    <content type="html">&lt;p&gt;Why I am I growing worried about reproducibility? For three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Reproducibility is a fringe movement in the sciences now.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Reproducibility is hard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;3.&lt;/p&gt;

&lt;p&gt;Right now, I could walk to the hardware store, buy some pea seeds, and replicate genetics research that&amp;#8217;s 150 years old. I could also replicate just Mendel&amp;#8217;s analysis with his raw data. However, I can&amp;#8217;t&lt;/p&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>Using Bioconductor to Analyze your 23andme Data</title>
    <link href="http://vincebuffalo.org/notes/2012/03/12/23andme-bioconductor.html"/>
    <updated>2012-03-12T00:00:00-07:00</updated>
    <id>http://vincebuffalo.org/notes/2012/03/12/23andme-bioconductor</id>
    <content type="html">&lt;span style='color: red'&gt;This is a working draft; I may add to this in
the future.&lt;/span&gt;
&lt;h1 id='using_bioconductor_to_analyze_your_23andme_data'&gt;Using Bioconductor to Analyze your 23andme Data&lt;/h1&gt;

&lt;p&gt;Bioconductor is one of the open source projects of which I am most fond. The documentation is excellent, the community wonderful, the development fast-paced, and the software &lt;em&gt;very&lt;/em&gt; well written. I&amp;#8217;ll introduce the power of Bioconductor while exploring some raw SNP data from &lt;a href='23andme.com'&gt;23andme.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll be using a new package in the development branch (due to be released with Bioconductor version 2.10 very soon) called &lt;code&gt;gwascat&lt;/code&gt;. &lt;code&gt;gwascat&lt;/code&gt; is a package that serves as an interface to the &lt;a href='http://www.genome.gov/'&gt;NHGRI&amp;#8217;s&lt;/a&gt; database of genome-wide association studies. I&amp;#8217;ll also be using the development version of &lt;code&gt;AnnotationDbi&lt;/code&gt;, which you&amp;#8217;ll need to grab if you want to follow along.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re reading this after the release of 2.10, use &lt;code&gt;biocLite&lt;/code&gt; to download; otherwise install &lt;a href='http://www.bioconductor.org/packages/devel/bioc/html/gwascat.html'&gt;the source package&lt;/a&gt; via &lt;code&gt;R CMD INSTALL&lt;/code&gt;. Loading the package with &lt;code&gt;library(gwascat)&lt;/code&gt; creates a &lt;code&gt;GRanges&lt;/code&gt; instance of SNPs and their diseases. &lt;code&gt;GRanges&lt;/code&gt; is a fundamental data structure in &lt;code&gt;Bioconductor&lt;/code&gt; (specifically the &lt;code&gt;GenomicRanges&lt;/code&gt; package) that is designed to hold ranges on genomes efficiently, as well as metadata about the ranges. In this case, the object &lt;code&gt;gwrngs&lt;/code&gt; holds SNP ranges (well, locations) and metadata provided by the GWA studies in NHGRI&amp;#8217;s database.&lt;/p&gt;

&lt;p&gt;While 23andme provides a great interface to one&amp;#8217;s genotyping information and GWA research, Bioconductor offers a different way to explore and learn from your genotyping data.&lt;/p&gt;

&lt;h2 id='23andme_raw_data'&gt;23andme Raw Data&lt;/h2&gt;

&lt;p&gt;When I was considering 23andme, I ultimately persuaded by the fact that they release their raw genotype calls to users. Unfortunately they do so without SNP call confidence data, but in a personal correspondence with a 23andme representative they stated:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Data reproducibility of our genotyping platforms is estimated at about 99.9%. Average call rate is about 99%. When samples do not meet sufficient call rate thresholds, we repeat the analysis, and/or request a new sample. We do not return data to customers that does not meet our quality thresholds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, 99.9% sounds like a lot, but considering there are 960,545 SNPs being called, it&amp;#8217;s not &lt;em&gt;that&lt;/em&gt; high.&lt;/p&gt;

&lt;p&gt;To retrieve raw data, simply click the &amp;#8220;Account&amp;#8221; link at the top of the page (after you&amp;#8217;ve signed in) and click &amp;#8220;Browse Raw Data&amp;#8221;. There should be a download link. If you&amp;#8217;ve never used GPG to encrypt a file, now is the time to learn; keep your SNP data encrypted.&lt;/p&gt;

&lt;p&gt;The file 23andme provides has four columns: rs ID, chromosome, position, and genotype.&lt;/p&gt;

&lt;h2 id='loading_raw_data_into_r'&gt;Loading Raw Data into R&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;read.table&lt;/code&gt; to load this data in R. It&amp;#8217;s a lot of data, so providing this function with information about the type of data can speed this up quite a bit. Here is the code I used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;d &amp;lt;- read.table(&amp;quot;data/genome_Vince_Buffalo_Full_20120313162059.txt&amp;quot;, sep=&amp;quot;\t&amp;quot;, 
               colClasses=c(&amp;quot;character&amp;quot;, &amp;quot;character&amp;quot;, &amp;quot;numeric&amp;quot;, &amp;quot;character&amp;quot;),
               col.names=c(&amp;quot;rsid&amp;quot;, &amp;quot;chrom&amp;quot;, &amp;quot;position&amp;quot;, &amp;quot;genotype&amp;quot;),
               header=FALSE)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may notice that chromosome has the class &amp;#8220;character&amp;#8221; - this is because there are chromosomes X, Y, and MT (for mitochondrial). For later plotting purposes, it&amp;#8217;s good to make this an ordered factor:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tmp &amp;lt;- d$chrom
d$chrom = ordered(d$chrom, levels=c(seq(1, 22), &amp;quot;X&amp;quot;, &amp;quot;Y&amp;quot;, &amp;quot;MT&amp;quot;))

## It&amp;#39;s never a bad idea to check your work
stopifnot(all(as.character(tmp) == as.character(d$chrom)))&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='where_are_the_snps_23andme_genotypes'&gt;Where are the SNPs 23andme Genotypes?&lt;/h2&gt;

&lt;p&gt;Using &lt;a href='http://had.co.nz/'&gt;Hadley Wickham&amp;#8217;s&lt;/a&gt; excellent &lt;code&gt;ggplot2&lt;/code&gt; package, we can look at the distribution of SNPs by chromosome:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ggplot(d) + geom_bar(aes(chrom))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src='/images/23andme_chrom_dist.png' alt='distribution of SNPs by chromosome' /&gt;&lt;/p&gt;

&lt;p&gt;This isn&amp;#8217;t providing information on SNP density as much as it is chromosome length (except X). We&amp;#8217;ll take a more detailed look a bit later.&lt;/p&gt;

&lt;p&gt;Another really wonderful aspect of Bioconductor is that the project isn&amp;#8217;t just a repository of code: it also stores annotation, full genomes, and experimental data. Such packaged data is the foundating of reproducible bioinformatics, as you no longer have to worry about keeping track of data versions and storing downloaded data yourself. If you need to work with cutting edge data from Ensembl or UCSC tracks, the packages &lt;code&gt;biomaRt&lt;/code&gt; and &lt;code&gt;rtracklayer&lt;/code&gt; work well.&lt;/p&gt;

&lt;h2 id='a_quick_demonstration_of_genomicranges_and_bioconductor_annotation_packages'&gt;A Quick Demonstration of GenomicRanges and Bioconductor Annotation Packages&lt;/h2&gt;

&lt;p&gt;Suppose I want to see if any of my SNPs fall in the APOE gene region. For this, I&amp;#8217;ll need transcript annotation data, as this tells me the range and chromosome of this gene. If I wished to create a fresh database of exon, gene, transcript, and splicing data, I could with the &lt;code&gt;GenomicFeature&lt;/code&gt; package. This package has methods for building &lt;code&gt;transcriptDb&lt;/code&gt; objects from the Known Gene track from UCSC, as well as Ensembl databases. However, I&amp;#8217;ll just use a pre-packaged version, &lt;code&gt;TxDb.Hsapiens.UCSC.hg18.knownGene&lt;/code&gt;. I use hg18 rather than hg19 because this is the build that 23andme&amp;#8217;s coordinates reference.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;library(TxDb.Hsapiens.UCSC.hg18.knownGene)
txdb &amp;lt;- TxDb.Hsapiens.UCSC.hg18.knownGene
class(txdb) ## do some digging around!&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;transcriptDb&lt;/code&gt; objects have nice accessor functions for accessing their components. Behind the scenes, everything is in SQLite and very efficient (are you seeing why I love Bioconductor?).&lt;/p&gt;

&lt;p&gt;If we look at the transcripts with the &lt;code&gt;transcripts&lt;/code&gt; accessor function, we see it&amp;#8217;s a &lt;code&gt;GenomicRanges&lt;/code&gt; object:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;transcripts(txdb)
GRanges with 66803 ranges and 2 elementMetadata values:
          seqnames               ranges strand   |     tx_id     tx_name
             &amp;lt;Rle&amp;gt;            &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt;   | &amp;lt;integer&amp;gt; &amp;lt;character&amp;gt;
      [1]     chr1     [  1116,   4121]      +   |         1  uc001aaa.2
      [2]     chr1     [  1116,   4272]      +   |         2  uc009vip.1
      [3]     chr1     [ 19418,  20957]      +   |        26  uc009vjg.1
      [4]     chr1     [ 55425,  59692]      +   |        28  uc009vjh.1
      [5]     chr1     [ 58954,  59871]      +   |        29  uc001aal.1
      [6]     chr1     [310947, 310977]      +   |        33  uc001aaq.1
      [7]     chr1     [311009, 311086]      +   |        34  uc001aar.1
      [8]     chr1     [314323, 314353]      +   |        35  uc001aas.1
      [9]     chr1     [314354, 314385]      +   |        36  uc001aat.1
      ...      ...                  ...    ... ...       ...         ...
  [66795]     chrY [25318610, 25368905]      -   |     33721  uc004fwl.1
  [66796]     chrY [25318610, 25368905]      -   |     33722  uc010nxm.1
  [66797]     chrY [25586438, 25607639]      -   |     33731  uc004fws.1
  [66798]     chrY [25739178, 25740308]      -   |     33732  uc004fwt.1
  [66799]     chrY [25949151, 25949179]      -   |     33733  uc004fwu.1
  [66800]     chrY [26012854, 26012887]      -   |     33734  uc004fww.1
  [66801]     chrY [26015033, 26015066]      -   |     33735  uc004fwx.1
  [66802]     chrY [26015782, 26015809]      -   |     33737  uc004fwy.1
  [66803]     chrY [26016792, 26016820]      -   |     33738  uc004fwz.1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To interact with the wealth of data behind a &lt;code&gt;transcriptDb&lt;/code&gt; object, we often group individual ranges into groups, leaving us with a &lt;code&gt;GRangesList&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tx.by.gene &amp;lt;- transcriptsBy(txdb, &amp;quot;gene&amp;quot;)
tx.by.gene
GRangesList of length 20121:
$1 
GRanges with 2 ranges and 2 elementMetadata values:
      seqnames               ranges strand |     tx_id     tx_name
         &amp;lt;Rle&amp;gt;            &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt; | &amp;lt;integer&amp;gt; &amp;lt;character&amp;gt;
  [1]    chr19 [63549984, 63556677]      - |     61027  uc002qsd.2
  [2]    chr19 [63551644, 63565932]      - |     61033  uc002qsf.1

$10 
GRanges with 2 ranges and 2 elementMetadata values:
      seqnames               ranges strand | tx_id    tx_name
  [1]     chr8 [18293035, 18303003]      + | 26503 uc003wyw.1
  [2]     chr8 [18301794, 18302666]      + | 26504 uc010lte.1

$100 
GRanges with 2 ranges and 2 elementMetadata values:
      seqnames               ranges strand | tx_id    tx_name
  [1]    chr20 [42681577, 42713790]      - | 62142 uc002xmj.1
  [2]    chr20 [42681577, 42713790]      - | 62143 uc010ggt.1

...
&amp;lt;20118 more elements&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Holy &lt;code&gt;GRangeList&lt;/code&gt; batman! These are the transcripts grouped by gene. There are other methods for grouping by CDS and exons (&lt;code&gt;cdsBy&lt;/code&gt; and &lt;code&gt;exonsBy&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The names of the list elements are Entrez gene IDs. We can look up specific genes with another Bioconductor annotation package, &lt;code&gt;org.Hs.eg.db&lt;/code&gt;. There are org.* annotation packages for many organisms. You can forge your own and interact with them with the &lt;code&gt;AnnotationDbi&lt;/code&gt; package. I&amp;#8217;m using a development version of this package that has a new slick SQL-like interface; it will be widely available with the upcoming 2.10 release.&lt;/p&gt;

&lt;p&gt;Suppose I want to convert the Entrez Gene IDs to gene names. The &amp;#8220;eg&amp;#8221; in org.Hs.eg.db refers to Entrez Gene IDs. Printing the &lt;code&gt;org.Hs.eg.db&lt;/code&gt; object gives a nice list of information. Let&amp;#8217;s look for the APOE gene&amp;#8217;s Entrez Gene ID.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;library(org.Hs.eg.db)
cols(org.Hs.eg.db)
  [1] &amp;quot;ENTREZID&amp;quot;     &amp;quot;ACCNUM&amp;quot;       &amp;quot;ALIAS&amp;quot;        &amp;quot;CHR&amp;quot;          &amp;quot;ENZYME&amp;quot;      
  [6] &amp;quot;GENENAME&amp;quot;     &amp;quot;MAP&amp;quot;          &amp;quot;OMIM&amp;quot;         &amp;quot;PATH&amp;quot;         &amp;quot;PMID&amp;quot;        
 [11] &amp;quot;REFSEQ&amp;quot;       &amp;quot;SYMBOL&amp;quot;       &amp;quot;UNIGENE&amp;quot;      &amp;quot;CHRLOC&amp;quot;       &amp;quot;CHRLOCEND&amp;quot;   
 [16] &amp;quot;PFAM&amp;quot;         &amp;quot;PROSITE&amp;quot;      &amp;quot;ENSEMBL&amp;quot;      &amp;quot;ENSEMBLPROT&amp;quot;  &amp;quot;ENSEMBLTRANS&amp;quot;
 [21] &amp;quot;UNIPROT&amp;quot;      &amp;quot;UCSCKG&amp;quot;       &amp;quot;GO&amp;quot;          &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These are the columns we can query out. Certain keys exist: we can access these using &lt;code&gt;keytypes()&lt;/code&gt;. Using it all together, we can extract the Entrez Gene ID:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;select(org.Hs.eg.db, keys=&amp;quot;APOE&amp;quot;, cols=c(&amp;quot;ENTREZID&amp;quot;, &amp;quot;SYMBOL&amp;quot;, &amp;quot;GENENAME&amp;quot;), 
       keytype=&amp;quot;SYMBOL&amp;quot;)
SYMBOL ENTREZID         GENENAME
APOE      348 apolipoprotein E&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, we can look for this in our &lt;code&gt;tx.by.gene&lt;/code&gt; &lt;code&gt;GRangesList&lt;/code&gt;. A word of caution: Entrez Gene IDs are &lt;strong&gt;names&lt;/strong&gt; and thus they need to be quoted when working with &lt;code&gt;GRangesList&lt;/code&gt; objects from transcript databases.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tx.by.gene[&amp;quot;348&amp;quot;]
GRangesList of length 1:
$348 
GRanges with 1 range and 2 elementMetadata values:
      seqnames               ranges strand |     tx_id     tx_name
         &amp;lt;Rle&amp;gt;            &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt; | &amp;lt;integer&amp;gt; &amp;lt;character&amp;gt;
  [1]    chr19 [50100879, 50104490]      + |     59642  uc002pab.1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If I had used &lt;code&gt;tx.by.gene[348]&lt;/code&gt; the 348th element of the list would have been returned, not the transcript data for the APOE gene (which has Entrez Gene ID &amp;#8220;348&amp;#8221;).&lt;/p&gt;

&lt;p&gt;Now, do any SNPs fall in this region? Let&amp;#8217;s build a &lt;code&gt;GRanges&lt;/code&gt; object from my genotyping data, and look for overlaps. Before I do, it&amp;#8217;s worth mentioning another gotcha about working with bioinformatics data: chromosome naming schemes. Different databases use all sorts of schemes, and you should always check them. 23andme returns just numbers, X, Y, and MT. Let&amp;#8217;s change it to use the same as the Bioconductor annotation.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# CAREFUL: use levels() to check that you&amp;#39;re making new factor names
# that correspond to the old ones!
levels(d$chrom) &amp;lt;- paste(&amp;quot;chr&amp;quot;, c(1:22, &amp;quot;X&amp;quot;, &amp;quot;Y&amp;quot;, &amp;quot;M&amp;quot;), sep=&amp;quot;&amp;quot;)
my.snps &amp;lt;- with(d, GRanges(seqnames=chrom, 
                   IRanges(start=position, width=1), 
                   rsid=rsid, genotype=genotype)) # this goes into metadata&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, let&amp;#8217;s find overlaps using, well, &lt;code&gt;findOverlaps&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;apoe.i &amp;lt;- findOverlaps(tx.by.gene[&amp;quot;348&amp;quot;], my.snps)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;apoe.i&lt;/code&gt; is an object of class &lt;code&gt;RangesMatching&lt;/code&gt;. Note that had we not matched chromosome names, Bioconductor gives us a nice warning that sequence names don&amp;#8217;t match. We could look at the slots of &lt;code&gt;apoe.i&lt;/code&gt; but output can be seen with &lt;code&gt;matchMatrix&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;hits &amp;lt;- matchMatrix(apoe.i)[, &amp;quot;subject&amp;quot;]
hits
 [1] 873650 873651 873652 873653 873654 873655 873656 873657 873658 873659
[11] 873660 873661 873662 873663 873664 873665 873666 873667 873668 873669
[21] 873670 873671 873672 873673 873674 873675 873676&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So in our subject, we have two hits. Let&amp;#8217;s dig them up in our SNP &lt;code&gt;GRanges&lt;/code&gt; object:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;my.snps[hits]
GRanges with 27 ranges and 2 elementMetadata values:
       seqnames               ranges strand   |        rsid    genotype
          &amp;lt;Rle&amp;gt;            &amp;lt;IRanges&amp;gt;  &amp;lt;Rle&amp;gt;   | &amp;lt;character&amp;gt; &amp;lt;character&amp;gt;
   [1]    chr19 [50101007, 50101007]      *   |    rs440446          CG
   [2]    chr19 [50101842, 50101842]      *   |    rs769449          GG
   [3]    chr19 [50102284, 50102284]      *   |    rs769450          AG
   [4]    chr19 [50102751, 50102751]      *   |    rs769451          TT
   [5]    chr19 [50102874, 50102874]      *   |    i5000209          GG
   [6]    chr19 [50102904, 50102904]      *   |    i5000208          GG
   [7]    chr19 [50102940, 50102940]      *   |    i5000201          CC
   [8]    chr19 [50102991, 50102991]      *   |  rs28931576          AA
   [9]    chr19 [50103697, 50103697]      *   |  rs11542040          CC
   ...      ...                  ...    ... ...         ...         ...
  [19]    chr19 [50104077, 50104077]      *   |    i5000212          GG
  [20]    chr19 [50104118, 50104118]      *   |    i5000210          GG
  [21]    chr19 [50104129, 50104129]      *   |    i5000213          CC
  [22]    chr19 [50104154, 50104154]      *   |    i5000207          TT
  [23]    chr19 [50104177, 50104177]      *   |    i5000219          GG
  [24]    chr19 [50104180, 50104180]      *   |    i5000218          GG
  [25]    chr19 [50104198, 50104198]      *   |    i5000206          CC
  [26]    chr19 [50104268, 50104268]      *   |    i5000204          GG
  [27]    chr19 [50104333, 50104333]      *   |  rs28931579          AA&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, we can verify that these SNPs are in the APOE gene using the UCSC Genome Browser (we could actually pull open a browser to this spot from R using &lt;code&gt;rtracklayer&lt;/code&gt;, but I&amp;#8217;ll save that for another time). Be sure to use hg18/build 36! Note that my genotype information is there.&lt;/p&gt;

&lt;p&gt;The ApoE4 allele is rs429358(C) + rs7412(C). The most common allele (ApoE3, or e3/e3) is rs429358(T) + rs7412(C) which is what I have (that&amp;#8217;s a relief). There&amp;#8217;s a lot of established research that shows homozygous ApoE4 (that is rs429358(C/C) + rs7412(C/C)) leads to substantially higher risk of Alzeheimer&amp;#8217;s. According to &lt;a href='http://snpedia.com/index.php/ApoE4'&gt;SNPedia&lt;/a&gt;, James Watson requested he not learn his genotype at this locus, and Steven Pinker requested his ApoE data be removed from his PGP10 data.&lt;/p&gt;

&lt;h2 id='looking_for_risk_variants_using_'&gt;Looking for Risk Variants using &lt;code&gt;gwascat&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;We can use the metadata provided by &lt;code&gt;gwascat&lt;/code&gt; to further look for interesting variants in our 23andme data. I would recommend interpreting this data with caution, as summarizing these findings in a single element metadata data frame is hard: there&amp;#8217;s definitely lost information.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;gwrngs&lt;/code&gt; &lt;code&gt;GRanges&lt;/code&gt; object has lots of metadata you should scan through with &lt;code&gt;elementMetadata(gwrngs)&lt;/code&gt;. The &lt;code&gt;Strongest.SNP.Risk.Allele&lt;/code&gt; is useful for seeing what you&amp;#8217;re at risk for. First, using the rs ID as a key, let&amp;#8217;s join our SNP data with the &lt;code&gt;gwrngs&lt;/code&gt; metadata:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gwrngs.emd &amp;lt;- as.data.frame(elementMetadata(gwrngs))
dm &amp;lt;- merge(d, gwrngs.emd, by.x=&amp;quot;rsid&amp;quot;, by.y=&amp;quot;SNPs&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can search for the risk allele in the 23andme genotype data with R and attach a vector of &lt;code&gt;i.have.risk&lt;/code&gt; to the &lt;code&gt;dm&lt;/code&gt; data frame:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;risk.alleles &amp;lt;- gsub(&amp;quot;[^\\-]*-([ATCG?])&amp;quot;, &amp;quot;\\1&amp;quot;, dm$Strongest.SNP.Risk.Allele)
i.have.risk &amp;lt;- mapply(function(risk, mine) {
  risk %in% unlist(strsplit(mine, &amp;quot;&amp;quot;))
}, risk.alleles, dm$genotype)
dm$i.have.risk &amp;lt;- i.have.risk&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that you have this data frame, you can mine it endlessly. You may want to sort by &lt;code&gt;Risk.Allele.Frequency&lt;/code&gt; and whether you have the risk. Because there are quite a few columns in the element metadata, it&amp;#8217;s nice to define a quick-summary subset:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;my.risk &amp;lt;- dm[dm$i.have.risk, ]

# define some relevant columns
rel.cols &amp;lt;- c(colnames(d), &amp;quot;Disease.Trait&amp;quot;, &amp;quot;Risk.Allele.Frequency&amp;quot;,
              &amp;quot;p.Value&amp;quot;, &amp;quot;i.have.risk&amp;quot;, &amp;quot;X95..CI..text.&amp;quot;)

head(my.risk[order(my.risk$Risk.Allele.Frequency), rel.cols], 1)
          rsid chrom position genotype Disease.Trait Risk.Allele.Frequency
2553 rs2315504 chr17 36300407       AC        Height                  0.01
     p.Value i.have.risk   X95..CI..text.
2553   8e-06        TRUE [NR] cm increase&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a rare variant, but the most important next question is, rare in who?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dm[which(dm$rsid == &amp;quot;rs2315504&amp;quot;), &amp;quot;Initial.Sample.Size&amp;quot;]
[1] 8,842 Korean individuals&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So this clearly doesn&amp;#8217;t mean much to me since I am of European ancestry. We can use &lt;code&gt;grep&lt;/code&gt; to find studies that mention &amp;#8220;European&amp;#8221;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;head(my.risk[grep(&amp;quot;European&amp;quot;, my.risk$Initial.Sample.Size), rel.cols], 30)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One interesting rs ID that popped up in this list of my data is rs10166942, which is lightly linked to migraines (from which I suffer).&lt;/p&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>Git Notes</title>
    <link href="http://vincebuffalo.org/notes/2012/03/11/git-notes.html"/>
    <updated>2012-03-11T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/notes/2012/03/11/git-notes</id>
    <content type="html">&lt;h1 id='git_notes'&gt;Git Notes&lt;/h1&gt;

&lt;p&gt;These are updated by me periodically. I have tried my best to illustrate common use cases, and the motivation for doing things the &amp;#8220;Git&amp;#8221; way.&lt;/p&gt;

&lt;h2 id='example_set_up'&gt;Example Set Up&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ll use this setup scenario frequently. In a suitable scatch repository (i.e. &lt;code&gt;git-sandbox&lt;/code&gt;), make a fake remote:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir fake-remote
cd fake-remote
git init --bare
cd ..&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, clone it, pretending you are two developers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone fake-remote jerry-repo
git clone fake-remote kramer-repo&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s assume you&amp;#8217;re Jerry and Kramer is another programmer in your group. As Jerry, let&amp;#8217;s make some changes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd jerry-repo
echo &amp;quot;an example file&amp;quot; &amp;gt; file.txt
git add file.txt
git commit -am &amp;quot;initial import&amp;quot;
git push origin master
cd ..&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, let&amp;#8217;s pretend we&amp;#8217;re Kramer and grab that recent commit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd kramer-repo
git pull origin master
cd ..&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='git_remote_tracking_branches'&gt;Git Remote Tracking Branches&lt;/h2&gt;

&lt;p&gt;Git remote tracking branches are similar to local branches (i.e. the kind you interact with &lt;code&gt;git checkout -b branch-name&lt;/code&gt; and see with &lt;code&gt;git
branch&lt;/code&gt;). However, you don&amp;#8217;t work on the remote branch directly, you work on a local branch that&amp;#8217;s &lt;em&gt;tracking&lt;/em&gt; this remote branch. For example, the most common workflow is to track a remote branch, then push your commits to it or pull commits down from it. Even though it&amp;#8217;s a &amp;#8220;remote&amp;#8221; tracking branch, the branch is stored locally (this branch doesn&amp;#8217;t disappear if you can&amp;#8217;t connected to the remote).&lt;/p&gt;

&lt;p&gt;Git remote tracking branches always have the format &lt;code&gt;remote-repo/remote-branch&lt;/code&gt;. After cloning a repository, you can set it to track a remote tracking branch with the &lt;code&gt;-u&lt;/code&gt; option of &lt;code&gt;git
push&lt;/code&gt;, e.g. &lt;code&gt;git push -u origin master&lt;/code&gt;. From now on, you can just use &lt;code&gt;git push&lt;/code&gt; when on this branch; this branch is &lt;em&gt;tracking&lt;/em&gt; &lt;code&gt;origin&lt;/code&gt;&amp;#8217;s &lt;code&gt;master&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt; shows local branches; to see remote branches use &lt;code&gt;git
branch -r&lt;/code&gt;, and to see &lt;em&gt;all&lt;/em&gt; branches, use &lt;code&gt;git branch -a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remote tracking branches are also what determine what is pulled/pushed when using &lt;code&gt;git pull&lt;/code&gt; and &lt;code&gt;git push&lt;/code&gt; without a remote repository and refspec (i.e. &lt;code&gt;git push origin master&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If the current branch is &lt;code&gt;new-feature&lt;/code&gt;, which tracks &lt;code&gt;origin/new-feature&lt;/code&gt;, then any branches checked out from &lt;code&gt;new-feature&lt;/code&gt; will &lt;em&gt;also&lt;/em&gt; track the remote too, unless &lt;code&gt;--no-track&lt;/code&gt; is added.&lt;/p&gt;

&lt;h2 id='git_fetch_and_merge_vs_git_pull'&gt;Git Fetch and Merge vs. Git Pull&lt;/h2&gt;

&lt;p&gt;Recall the above point that remote tracking branches are local, so (unlike Subversion) they function even when you&amp;#8217;re not able to connect to the remote. This gives an example of how elegant Git is: being so similar to regular branches, Git remote tracking branches can be merged into local branches. This is precisely what goes on behind the scenes with &lt;code&gt;git pull&lt;/code&gt;. Here&amp;#8217;s an example. First, let&amp;#8217;s set it up such that a developer in your group, Kramer, made some changes, committed them, then pushed them to the remote.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# assuming you&amp;#39;re in the right directory
cd kramer-repo
echo &amp;quot;kramer adding gibberish&amp;quot; &amp;gt;&amp;gt; file.txt
git commit -am &amp;quot;I added some gibberish&amp;quot;
git push
cd ..&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, imagine you (Jerry) have made some commits but want to see what the status of the remote looks like. &lt;code&gt;git remote show&lt;/code&gt; can be used to see if the local remote tracking branch is out of date.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;vinceb@poisson$ git remote show origin
* remote origin
  Fetch URL: /Users/vinceb/Desktop/git-sandbox/fake-remote
  Push  URL: /Users/vinceb/Desktop/git-sandbox/fake-remote
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for &amp;#39;git pull&amp;#39;:
    master merges with remote master
  Local ref configured for &amp;#39;git push&amp;#39;:
    master pushes to master (local out of date)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So we are out of date! We can see these commits before merging them in with &lt;code&gt;git fetch&lt;/code&gt;. &lt;code&gt;git fetch&lt;/code&gt; updates your remote tracking branch with the new changes, allowing you to &lt;code&gt;diff&lt;/code&gt; branches just as you would with two regular branches.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;vinceb@poisson$ git diff master origin/master
diff --git a/file.txt b/file.txt
index 4e850ce..34ceb34 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1,2 @@
 an example file&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;git log origin/master master&lt;/code&gt; also works. &lt;code&gt;git log origin/master
^master&lt;/code&gt; shows us just the new commits. We could really explore these commits by checkout out the remote tracking branch (but consider this to be &amp;#8220;taking a visit&amp;#8221;; don&amp;#8217;t commit anything). Suppose we did, and we decide we want to merge them with our current branch. For this, we just use &lt;code&gt;git merge&lt;/code&gt;: remember remote tracking branches are just branches!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;vinceb@poisson$ git branch ## always check what branch you&amp;#39;re on!
* master
vinceb@poisson$ git merge origin/master
Updating ee922a9..8c8c240
Fast-forward
 file.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that &lt;code&gt;git pull&lt;/code&gt; basically is &lt;code&gt;git fetch &amp;amp;&amp;amp; git merge&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='great_resources'&gt;Great resources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://ftp.newartisans.com/pub/git.from.bottom.up.pdf'&gt;Git From the Ground Up&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://gitref.org/'&gt;Git Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>The Beauty of Bioconductor</title>
    <link href="http://vincebuffalo.org/essays/2012/03/08/the-beauty-of-bioconductor.html"/>
    <updated>2012-03-08T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/essays/2012/03/08/the-beauty-of-bioconductor</id>
    <content type="html">&lt;h1 id='the_beauty_of_bioconductor'&gt;The Beauty of Bioconductor&lt;/h1&gt;

&lt;h2 id='introduction'&gt;Introduction&lt;/h2&gt;

&lt;p&gt;In talking with bioinformaticians, biologists, and other researchers, I&amp;#8217;ve seen some worrying trends in computation in the sciences. I plan on writing about these extensively in the future, as I believe computation in the sciences will not scale well to face the huge wealth of data coming experiments will provide. This is not due to algorithmic or hardware limitations, but rather to the fact that scientific programmers simply do not have the same standards and practices that the software industry does.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/big-data-breakpoint.png' alt='A big data breaking point?' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How do we prevent a big genomic data breaking point?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Three events are simultaneously occurring that could endanger the validity of scientific conclusions in the future. First, new technology is providing the average scientist with more data than ever before. Genomics is the prime example of this: the average biologist can now sequence multiple samples simultaneously whereas this would be prohibitively expensive just a few years earlier. As metabolomic and proteomic data are increasingly incorporated into research alongside genomic data, the work done by bioinformaticians will increase significantly. More lines of code to write and more data to process under deadlines will doubtlessly lead to mistakes.&lt;/p&gt;

&lt;p&gt;The second contributing factor is that more researchers are writing code and analyzing their own data rather hiring a bioinformatician or statistician. It&amp;#8217;s an awesome and commendable occurrence, but sadly academic institutions don&amp;#8217;t adequately prepare researchers to code to high standards. Also, in many cases these researchers learn to program by analyzing their own experimental data, rather than example or &amp;#8220;toy&amp;#8221; data. This makes &amp;#8220;silent&amp;#8221; mistakes (i.e. those that don&amp;#8217;t prompt an error, but lead to incorrect results) impossible to discover as the actual results are not known.&lt;/p&gt;

&lt;p&gt;The last contributing factor is that there&amp;#8217;s not a strong expectation that coding standards and software engineering practices be upheld in the sciences. There&amp;#8217;s a strong &lt;a href='http://en.wikipedia.org/wiki/Cowboy_coding#Inexperienced_developers'&gt;cowboy coding&lt;/a&gt; culture in scientific programming. In this mindset, the coding is done when the data is processed, &lt;em&gt;not&lt;/em&gt; when the data is processed, the code documented, the unit tests passed, the code checked into a repository, etc. The scientific community needs to embrace the idea that proper data analysis takes time: perhaps as long or longer than gathering experimental data.&lt;/p&gt;

&lt;p&gt;In future essays I&amp;#8217;ll talk more about these issues in depth. This stuff honestly keeps me (and other people I know) awake at night. I worry humanity may face a &lt;a href='http://en.wikipedia.org/wiki/Thalidomide'&gt;Thalidomide-like&lt;/a&gt; event in the future due to an error in scientific programming.&lt;/p&gt;

&lt;p&gt;However, here I want to commend a project that I feel is underutilized in the biology and bioinformatics communities: Bioconductor. It&amp;#8217;s worthy of praise as both an example of, and tool to aid in excellency in bioinformatics programming. I&amp;#8217;ll focus primarily on its capacity for handling high throughput sequencing data (even though it handles data from other assays very well too).&lt;/p&gt;

&lt;h2 id='where_is_bioinformatics'&gt;Where is Bioinformatics?&lt;/h2&gt;

&lt;p&gt;Currently, many bioinformatics analyses go something like this: experimental data is received, and then a bioinformatician downloads vast amounts of other data relating to the experiment from web resource such as the UCSC Genome Browser, Ensembl, Phytozome, etc. Often this includes genome assemblies, transcript sequences, and annotation data. Then, application code (alignment software, assemblers, SNP finding tools, etc) are downloaded and compiled. These tools are used alongside custom code written that combines downloaded data with the experimental data, and this produces results that are interpreted. Intermediate results may be fed into other online tools and databases like &lt;a href='http://david.abcc.ncifcrf.gov/'&gt;DAVID&lt;/a&gt; or &lt;a href='http://www.reactome.org/ReactomeGWT/entrypoint.html'&gt;Reactome&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, this is a bad model if one wants the analysis to be reproducible. The common weakness is that web resources can be unstable. It&amp;#8217;s then necessary for the researcher to record software and data versions manually. Even if the researcher dutifully complies, outside databases and code repositories may disappear and leave the project unable to be reproduced. Researchers truly invested in conducting reproducible research then have to store data and software versions themselves, which given the scale of genomic data is quite a burden.&lt;/p&gt;

&lt;p&gt;Thus, three things currently perplex reproducible research in bioinformatics: the scale of both experimental and other required data prevents easy self-archival, the fast-paced development of bioinformatics tools could lead to differing results across versions, and the overwhelming prevalence of web-based data resources and applications which are not easily reproducible.&lt;/p&gt;

&lt;h2 id='the_bioconductor_solution'&gt;The Bioconductor Solution&lt;/h2&gt;

&lt;p&gt;Bioconductor has, in my opinion, the best solution to these problems. First, Bioconductor stores past versions of its packages back to the earliest releases. Past experiments can be replicated using the exact version of software that was used for the actual analysis.&lt;/p&gt;

&lt;p&gt;Second, Bioconductor stores data as packages. Pre-packaged versioned data is a cornerstone of reproducible research. For example, suppose I am working with human RNA-seq data. This requires transcript annotation data, which could be downloaded from an online resource. To be reproducible, this requires that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The webhost be up indefinitely.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The URL remain stable and point to the exact same resource.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The user provide not only a URL but the version of data/software downloaded.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;That the external resource provider (i.e. database or application developer) actually update their versions accordingly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For absolute best practice, it&amp;#8217;s also necessary to MD5 checksum the data and record this value to maintain any data gathered from the same source is the exact same.&lt;/p&gt;

&lt;p&gt;In contrast, consider how I would load human transcript data into R with Bioconductor:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;library(TxDb.Hsapiens.UCSC.hg19.knownGene)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The versioning here is done explicitly in the package name: hg19. I could also easily record the state of all my Bioconductor packages and my session with &lt;code&gt;sessionInfo()&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; sessionInfo()
R version 2.14.1 (2011-12-22)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] annotate_1.32.2       AnnotationDbi_1.17.23 Biobase_2.14.0       
 [4] BiocGenerics_0.1.12   DBI_0.2-5             DESeq_1.6.1          
 [7] genefilter_1.36.0     geneplotter_1.32.1    grid_2.14.1          
 [10] IRanges_1.12.6        RColorBrewer_1.0-5    RSQLite_0.11.1       
 [13] splines_2.14.1        survival_2.36-12      xtable_1.7-0     &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Entire genomes are also packaged via the &lt;a href='http://www.bioconductor.org/packages/release/bioc/html/BSgenome.html'&gt;&lt;code&gt;BSgenome&lt;/code&gt; package&lt;/a&gt; (BS refers here to &lt;a href='http://www.bioconductor.org/packages/2.9/bioc/html/Biostrings.html'&gt;Biostrings&lt;/a&gt;). If the data in packages is not sufficiently recent, the &lt;a href='http://www.bioconductor.org/packages/release/bioc/html/GenomicFeatures.html'&gt;&lt;code&gt;GenomicFeatures&lt;/code&gt;&lt;/a&gt; package provides a programmatic way of downloading, packaging, and using data from BioMart and UCSC Genome Browser tracks, and provides functions for saving and loading &lt;code&gt;transcriptDb&lt;/code&gt; objects from such resources. Recently Duncan Temple Lang and I were speaking about reproducible research, and he said &amp;#8220;people adopt best practices when they&amp;#8217;re right in front of their face&amp;#8221;. Bioconductor&amp;#8217;s tools do just that. Furthermore, Bioconductor has strict coding and documentation standards (much stricter than CRAN actually), which ensures user-contributed packages are high quality.&lt;/p&gt;

&lt;h2 id='information_leakage_and_statistics_at_every_level'&gt;Information leakage and statistics at every level&lt;/h2&gt;

&lt;p&gt;When discussing R and Bioconductor with other researchers, it&amp;#8217;s easy to convince them to adopt both for analyzing statistical data - the data that comes in the very final stages of a bioinformatics analysis. It&amp;#8217;s usually much more difficult to convince them to consider working with high throughput sequencing data in Bioconductor. Folks complain that it&amp;#8217;s (1) not worth it to process sequencing data with Bioconductor tools or (2) it&amp;#8217;s not fast enough. I&amp;#8217;ll address the second point in a bit; more importantly I want to emphasize that it&amp;#8217;s &lt;strong&gt;absolutely&lt;/strong&gt; worth it to process sequencing data in Bioconductor.&lt;/p&gt;

&lt;p&gt;In analyzing genomic data, we take very, very, very high dimension data and try to condense it into biologically meaningful conclusions without being misleading or getting something wrong. Every step is about taking dense data and making it understandable: we take sequence reads and try to assemble them into larger contigs and scaffolds, we take cDNA reads and try to map them back to genomes to understand expression, etc. At each step, our tools make heuristic or statistical choices for us. Pipelines woefully ignore these choices because in most cases, after a step is completed, a script jumps to the next step.&lt;/p&gt;

&lt;p&gt;When I think about these steps, I try to assess what I think of as &amp;#8220;informational leakage&amp;#8221; in bioinformatics processing. Each step summarizes something, hopefully in a way without bias or too much noise. Informational leakage is the information that&amp;#8217;s lost between steps. Catastrophic information leakage occurs when we lose information that could have indicated whether the data is biased or incorrect. We can hedge the risk of information leakage when we use summary statistics between steps that try to capture this leaked information.&lt;/p&gt;

&lt;p&gt;Consider processing RNA-seq reads. The first step is usually quality control, i.e. removing adapter sequences and trimming off poor quality bases. Failing to gather summary statistics before and after each of these steps leads to potentially catastrophic information leakage. Suppose that an experiment with control and treatment groups, sequenced on two different lanes (bad experiment design!). If one lane has systematically lower 3&amp;#8217;-end quality than the other, quality trimming software will trim these bases off and lead one experimental group to have much shorter sequences than the other. The mapping rates will differ significantly, as shorter reads may map less uniquely. In the end, our data is completely confounded not only by the lane (and bad experimental design), but by our own tools! If these tools are being run in a pipeline without intermediate summary statistics being gathered, this catastrophic information leakage will go unnoticed.&lt;/p&gt;

&lt;p&gt;Loading sequencing data into R and using Bioconductor&amp;#8217;s tools earlier allows summary statistics to be gathered earlier and more easily (R is, after all, great for statistics and visualization), which I strongly believe will decrease the risk of catastrophic information leakage in genomics data analysis. This is why I wrote &lt;a href='http://bioconductor.org/packages/release/bioc/html/qrqc.html'&gt;&lt;code&gt;qrqc&lt;/code&gt;&lt;/a&gt;, which can provide quick summary statistics on sequencing read quality. Used before and after the application of quality tools, &lt;code&gt;qrqc&lt;/code&gt; can provide information not only on the state of the data, but also the effect of the tools.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/qrqc.png' alt='Sequence quality before and after quality trimming with qrqc' /&gt;&lt;/p&gt;

&lt;p&gt;With existing Bioconductor packages, many useful statistics can be gathered on whole reads, BAM mapping results, VCF files, etc.&lt;/p&gt;

&lt;h2 id='massive_power'&gt;Massive Power&lt;/h2&gt;

&lt;p&gt;The complaint that R is slow, and couldn&amp;#8217;t possibly be used with sequencing/mapping-level data is unwarranted. In reality, some of Bioconductor&amp;#8217;s core packages for working with high throughput sequencing data such as &lt;code&gt;Biostrings&lt;/code&gt; and &lt;code&gt;IRanges&lt;/code&gt; (the foundation of &lt;code&gt;GenomicRanges&lt;/code&gt;) are astoundingly fast because most of their backends are written in C. &lt;code&gt;Biostring&lt;/code&gt; actually uses external pointers to C structures and bit patterns to encode biological string data efficiently.&lt;/p&gt;

&lt;p&gt;In addition to being fast, they&amp;#8217;re also clever. &lt;code&gt;Biostrings&lt;/code&gt; implements an abstraction called a &amp;#8220;view&amp;#8221; on an &lt;code&gt;XString&lt;/code&gt; object, which efficiently represents multiple sections of the same string object (such as subsequences of interest). While I wouldn&amp;#8217;t write a short read aligner or assembler entirely in R, many bioinformatic tasks are more than sufficiently fast with Bioconductor tools.&lt;/p&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In evangelizing Bioconductor, I have two goals. First, I want to spread awareness that it&amp;#8217;s the best way to do reproducible bioinformatics that I think exists today. I want more people to use it just because I deeply care about the state of science and reproducibility. Second, I want to build excitement about this project so that more people will contribute. I believe that far too many high quality bioinformatics tools are written outside of Bioconductor. Packaging bioinformatics tools in Bioconductor forces the developer to adopt strict standards, write clear documentation, and open up a program to a large, active user base. Any results from a package&amp;#8217;s methods can then easily be evaluated using R, CRAN, or Bioconductor&amp;#8217;s existing tools.&lt;/p&gt;

&lt;p&gt;I also believe that large programs (like BLAST, and maybe assemblers) should provide better interfaces to R, to prevent information leakage in analysis. I&amp;#8217;m willing to bet that a large majority of bioinformatics tools could be outputting more statistics than they currently do that could be valuable in assessing their functionality. R interfaces to these bioinformatics tools will drastically make it easier for biologists and bioinformaticians to prevent information leakage.&lt;/p&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>Thoughts on Julia and R</title>
    <link href="http://vincebuffalo.org/essays/2012/03/07/thoughts-on-julia.html"/>
    <updated>2012-03-07T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/essays/2012/03/07/thoughts-on-julia</id>
    <content type="html">&lt;h1 id='thoughts_on_julia_and_r'&gt;Thoughts on Julia and R&lt;/h1&gt;

&lt;h2 id='hello_julia'&gt;Hello, Julia&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://julialang.org'&gt;Julia&lt;/a&gt; is an exciting new technical computing language. It&amp;#8217;s still in its infancy, but it&amp;#8217;s fast (see below), and already does a lot.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/julia_speed.png' alt='Comparison of Julia to other languages' /&gt;&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s been some excitement on Twitter about Julia. Excitement combined with open source often yields development, which then leads to further excitement, until a mature open source project arises. One of Julia&amp;#8217;s explicit goals is to challenge other statistical computing environments, including R.&lt;/p&gt;

&lt;h2 id='whats_wrong_with_r'&gt;What&amp;#8217;s wrong with R?&lt;/h2&gt;

&lt;p&gt;R is, without a doubt, changing the world. It&amp;#8217;s being used by industry giants like Facebook and Google, while also providing academic researchers in statistics, biology, psychology, and countless other fields with not only a free and open source statistical environment, but a huge number of user-contributed package through CRAN. Now methods papers in many fields are often accompanied by CRAN or Bioconductor packages. It&amp;#8217;s also a brilliant platform for reproducible, open research, as Bioconductor beautifully illustrates with packaged and version-controlled genomes, microarray probesets, etc.&lt;/p&gt;

&lt;p&gt;However, R is suffering from growing pains. For example, there are now 64-bit versions of R, however, vector indexing is still limited by &lt;code&gt;R_len_t&lt;/code&gt; (see definition in &lt;code&gt;src/include/Rinternals.h&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/* type for length of vectors etc */
typedef int R_len_t; /* will be long later, LONG64 or ssize_t on Win64 */
#define R_LEN_T_MAX INT_MAX&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It appears that one can simply change this to a long and recompile to increase the longest possible addressable vector, but no. Take a look at &lt;code&gt;R_euclidean&lt;/code&gt; in &lt;code&gt;library/stats/src/distance.c&lt;/code&gt; for an example why: almost all variables for iterating over elements in vectors are defined as integers and don&amp;#8217;t use this type. One would have to read through every function, and every line of code to fix this.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;R_len_t&lt;/code&gt; is just one example. Another issue is that R has been slow to adopt new compiler technologies (i.e. JIT, optional type indications, etc). R almost always gains speed from pushing stuff to C (the recent bytecode compiler is an exception). This isn&amp;#8217;t a problem, but it&amp;#8217;s a huge limitation to require developers to not only know R, but also C, and also how to interface the two. More modern languages (Java, as well as Python and Julia come to mind) spend more time tracking compiler technology developments and implementing them than R core does (again, Luke Tierney and the bytecode compiler are exceptions). It&amp;#8217;s still sometimes efficient to use C with these languages (consider &lt;a href='http://cython.org/'&gt;Cython&lt;/a&gt;), but developers in these language aren&amp;#8217;t cracking open Kernighan and Ritchie everytime they need to have a &lt;code&gt;for&lt;/code&gt; loop do something quickly.&lt;/p&gt;

&lt;p&gt;Another gripe I have is that R language development is somewhat closed. Despite a quickly expanding user base, the number of R core contributors is not increasing. I find it hard to believe this is due to lack of interest. It seems much more likely this is due to institutional reasons that need to be changed. The nice thing about language development that it&amp;#8217;s really hard, so opening up R to more contributors won&amp;#8217;t likely flood the existing core with bad ideas and patches. Personally I would dedicate much more time profiling, reading the source, and working on the R language if it were more open.&lt;/p&gt;

&lt;p&gt;The last gripe I have is that R is fragmented. Consider Python:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import re
re.search(r&amp;#39;R-([\d]+).([\d]+)&amp;#39;, &amp;quot;R-2.15&amp;quot;).groups()&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, consider R:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gsub(&amp;quot;R-([\\d]+)\\.([\\d]+)&amp;quot;, &amp;quot;\\1&amp;quot;, &amp;quot;R-2.15&amp;quot;)

# or

library(stringr)
str_match(&amp;quot;R-2.15&amp;quot;, &amp;quot;R-([0-9]+)\\.([0-9]+)&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, Python also has PyPI&amp;#8217;s &lt;a href='http://pypi.python.org/pypi/re2/'&gt;&lt;code&gt;re2&lt;/code&gt;&lt;/a&gt;, but most developers are using &lt;code&gt;re&lt;/code&gt;. The motivation behind &lt;code&gt;stringr&lt;/code&gt; is that R&amp;#8217;s currently family of string processing functions are horribly inconsistent:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (my ... to avoid writing all parameters)
grep(pattern, x, ...)
regexpr(pattern, text, ...)
gsub(pattern, replacement, x, ...)
strsplit(x, split, ...)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But rather than deprecate these and move forward, we now have &lt;em&gt;two&lt;/em&gt; sets of string processing functions. &lt;a href='http://github.com/search?langOverride=&amp;amp;language=R&amp;amp;q=str_extract&amp;amp;repo=&amp;amp;start_value=1&amp;amp;type=Code'&gt;Both are being used&lt;/a&gt;. I&amp;#8217;m not saying Hadley Wickham is to blame here; quite the contrary, he&amp;#8217;s trying to fix a very annoying problem in the language and should be commended. I think the community needs to be more open; for example, before writing a package that processes strings, let&amp;#8217;s discuss an implementation plan, deprecating old functions, etc. If not, in the future R will be highly fragmented, and end up with five different object orientation systems&amp;#8230; oh, wait.&lt;/p&gt;

&lt;h2 id='what_would_it_take_to_challenge_r'&gt;What would it take to &amp;#8220;challenge&amp;#8221; R?&lt;/h2&gt;

&lt;p&gt;Contributors to Julia are optimistic they can challenge R based on a solid foundation of JIT compiling, parallelism, and nice language semantics. I salute this optimism, but I think we need to realistically consider what it would take to &amp;#8220;challenge&amp;#8221; R.&lt;/p&gt;

&lt;p&gt;First, we would need to build an equal statistical computing environment. Consider moving all of &lt;code&gt;stats&lt;/code&gt;, &lt;code&gt;MASS&lt;/code&gt;, &lt;code&gt;graphics&lt;/code&gt;, &lt;code&gt;grid&lt;/code&gt;, etc to Julia. Is Julia sufficiently faster than R &lt;em&gt;will be&lt;/em&gt; in the time it takes to port these base packages? Remember, R is a moving target; despite my few earlier gripes, R will evolve and get faster. Now, consider adding the extremely popular CRAN packages like &lt;code&gt;ggplot2&lt;/code&gt; and &lt;code&gt;lattice&lt;/code&gt; to Julia. In the time it takes to port these, is Julia still sufficiently faster than R will be?&lt;/p&gt;

&lt;p&gt;Suppose it is still faster than R. What about after we port the rest of CRAN, and all of Bioconductor to Julia? My point isn&amp;#8217;t say that it&amp;#8217;s unimaginable that Julia will surpass R. It&amp;#8217;s that developers should really dissect what makes a successful language successful before they try to challenge it. I don&amp;#8217;t have a horse in this race; I would love to see Julia surpass R. But if all developers want is a fast environment to analyze large data sets using a wealth of methods and libraries, it may be a lot easier to make R faster than to develop a new fast language and hope/wait/beg the community to move over.&lt;/p&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>Some Ramblings on Machine Learning in Science</title>
    <link href="http://vincebuffalo.org/essays/2012/03/03/the-unbelievable-debate.html"/>
    <updated>2012-03-03T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/essays/2012/03/03/the-unbelievable-debate</id>
    <content type="html">&lt;h1 id='the_unbelievable_debate_some_ramblings_on_machine_learning_in_science'&gt;The Unbelievable Debate: Some Ramblings on Machine Learning in Science&lt;/h1&gt;

&lt;p&gt;In between refactoring some &lt;code&gt;qrqc&lt;/code&gt; code this morning and looking at RNA-seq data, I grabbed some cold brew coffee and caught up on some missed tweets. Admittedly, my brain glosses over most tweets, but &lt;a href='https://twitter.com/#!/drewconway/status/176725770885017600'&gt;this tweet&lt;/a&gt; from Drew Conway had the right mix of keywords to actually make me click and read the link:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The data science debate: domain expertise or machine learning? by @medriscoll http://bit.ly/zr17Z2&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I don&amp;#8217;t mean for this title to be inflammatory, but I do believe this debate is a bit unbelievable. Machine learning &lt;em&gt;is&lt;/em&gt; magical; I imagine that everyone that has studied it goes through a &lt;a href='http://en.wikipedia.org/wiki/Hype_cycle'&gt;hype cycle&lt;/a&gt;-like set of epiphanies. This is my hype cycle story, and why I believe machine learners need to calm down, collaborate with domain experts, and together tackle hard problems.&lt;/p&gt;

&lt;h2 id='social_sciences_and_machine_learning_caution'&gt;Social Sciences and Machine Learning Caution&lt;/h2&gt;
&lt;a title='Restored Phillips Machine, 1993 by LSE Library, on Flickr' href='http://www.flickr.com/photos/lselibrary/3990093924/'&gt;&lt;img height='500' src='http://farm3.staticflickr.com/2459/3990093924_2de07186ae.jpg' width='390' alt='Restored Phillips Machine, 1993' /&gt;&lt;/a&gt;
&lt;p&gt;&lt;em&gt;&lt;a href='http://en.wikipedia.org/wiki/Moniac'&gt;MONIAC&lt;/a&gt;: social science machine learning?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Biologists, it&amp;#8217;s true: I&amp;#8217;m not one of you. I&amp;#8217;m a transplant from the social sciences. Specifically, from political science and economics (with statistics too), where my interests lie in methodology and comparative politics.&lt;/p&gt;

&lt;p&gt;In the social sciences, the dimensionality of most problems is small enough that data mining is (at least in my experience) frowned upon. A lot of political data is collected by hand, often by undergraduates toiling away for meager pay as they try to understand some cryptic event coding protocol. There are some very large &lt;em&gt;p&lt;/em&gt; data sets: The &lt;a href='http://globalpolicy.gmu.edu/pitf/'&gt;Political Instability Task Force&amp;#8217;s&lt;/a&gt; data set is something I&amp;#8217;ll keep mentioning. Mining this data with algorithms &lt;em&gt;looking&lt;/em&gt; for interesting relationships was exactly how I was taught &lt;em&gt;not&lt;/em&gt; to do political science.&lt;/p&gt;

&lt;p&gt;I recall one story of a candidate giving a job talk mentioning he used forward step-wise regression to find interesting variables (in a presumably small &lt;em&gt;p&lt;/em&gt; data set) and three people immediately stood up and left. I was proud to be knowledgeable of, but avoid statistical learning techniques. Political science had flirted with neural networks to understand massive state failure data sets, but my endless gripe was there these were &lt;em&gt;predictive&lt;/em&gt;, not &lt;em&gt;causal&lt;/em&gt; models. The latter required some &lt;em&gt;a priori&lt;/em&gt; testable theory, often derived from an intimate knowledge of political crisis in a variety of countries. Just as I thought biologists knew &lt;em&gt;c. elegans&lt;/em&gt; or &lt;em&gt;s. cerevisiae&lt;/em&gt; well enough to form interesting experiment ideas, political scientists knew many political crises well enough to form theories and test them on a larger set of data in a quantitatively rigorous fashion. I also believed that predictive models of state failure may predict recorded (even when out-sample!) state failures well, but a model backed in a good theory that fits existing data slightly less well could predict unseen cases even better (&lt;a href='http://www.amazon.com/Predictioneers-Game-Brazen-Self-Interest-Future/dp/1400067871'&gt;Bruce Bueno de Mesquita has an entire wonderful book about game theory being such a model&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id='the_machine_learning_awakening'&gt;The Machine Learning Awakening&lt;/h2&gt;

&lt;p&gt;When I made the jump to analyzing gene expression data, I was initially astounded at how many algorithms were thrown at it. I had this vision of the hard sciences having randomization and experimentation at their disposal to lead to the purest causal findings. Looking for any differences in 30,000 genes&amp;#8217; expression values and then forming hypotheses after seemed backwards. Microarrays shocked biology with what they revealed about cancer and the cell, but they probably shocked the methods of experimental biology more. If your average biologist had a tenuous knowledge of p-values to begin with, now microarrays analysts were throwing around false discovery rates, empirical Bayesian techniques, Storey&amp;#8217;s q-value, etc.&lt;/p&gt;

&lt;p&gt;However, as I analyzed more and more sets of data, the initial reluctance I had about employing machine learning algorithms disappeared. In hype cycle terms, I was climbing the peak of inflated expectations. A quote from Michael E. Driscoll&amp;#8217;s article captures this excitement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Claudia Perlich, a three-time winner of the KDD Nuggets competition, stood up and shared how she had won contests in domains as varied as &amp;#8220;breast cancer, movie prediction, and sales performance - and I can tell you I knew next to nothing about those things when I started.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This optimism is abundant, and not entirely without justification. Coming from a non-biological background yet thoroughly understanding machine learning provides an immensely satisfying feeling of understanding of the cell. Employing all sorts of machine learning techniques, I could find &amp;#8220;biologically interesting&amp;#8221; genes in data sets and help biologists understand the cell.&lt;/p&gt;

&lt;h2 id='a_few_epiphanies_and_a_dip_of_disillusionment'&gt;A Few Epiphanies and a Dip of Disillusionment&lt;/h2&gt;

&lt;p&gt;The Hype Cycle&amp;#8217;s lowest stage is the &amp;#8220;trough of disillusionment&amp;#8221;. Machine learning in biology certainly hasn&amp;#8217;t had its trough (and I don&amp;#8217;t think it will), but it is priming up to have its &amp;#8220;slope of enlightenment&amp;#8221; and &amp;#8220;plateau of productivity&amp;#8221;. There will be future machine learning hype cycles in biology, especially as multiple heterogeneous data sets need to be simultaneously mined to understand the cell with the systems approach.&lt;/p&gt;

&lt;p&gt;My personal dip didn&amp;#8217;t happen because machine learning left me with a particularly terrible result - it occurred because (1) because of an interaction I had with an experimental biologist and (2) I realized how wonderfully complex the cell is.&lt;/p&gt;

&lt;h3 id='lets_put_that_in_this'&gt;Let&amp;#8217;s Put That in This&lt;/h3&gt;

&lt;p&gt;The first interaction I had was with a graduate student friend of mine. We were discussing an interesting finding the Korf Lab made: that some introns lead to increased expression (&lt;a href='http://www.frontiersin.org/plant_genetics_and_genomics/10.3389/fpls.2011.00098/full'&gt;paper here&lt;/a&gt;). Introns traditionally haven&amp;#8217;t had the same attention as promoters of enhancers in regulating gene expression. A member of the Korf lab had previously mentioned intron-mediated expression in passing to me, and I immediately started imagining what ways I could look for such an effect &lt;em&gt;in silico&lt;/em&gt;. As I understood it, &lt;em&gt;in silico&lt;/em&gt; was how it was first discovered, further increasing my admiration of algorithms applied to biology. When my friend mentioned it again, the first thing she said was, &amp;#8220;well, we just need to take that intron and put it in something&amp;#8221;.&lt;/p&gt;

&lt;p&gt;I immediately agreed, but I realized something: I hadn&amp;#8217;t thought of that simple step the first time I thought about intron-mediated expression. Machine learning can bring so much wealth in finding interesting relationships that my mind had glossed over the most important question in science: whether these relationships were spurious or causal. This is why my training in the social sciences was rigidly anti-machine learning: it&amp;#8217;s far too easy to let our thought processes about &lt;em&gt;understanding&lt;/em&gt; a complex system be biased by some spurious relationships machine learning and predictive models can quickly give us.&lt;/p&gt;

&lt;h3 id='the_complexity_of_the_cell'&gt;The Complexity of the Cell&lt;/h3&gt;

&lt;p&gt;The epiphany was gradual (and still occurring): the cell is wonderfully complex, or as my mind puts it &amp;#8220;fucking awesomely complex&amp;#8221;. Machine learning applied to gene expression data gives valuable insights into a complex system, but it&amp;#8217;s really a messy snapshot. I think we&amp;#8217;ll look at current pristine RNA-seq experiments in twenty years and we&amp;#8217;ll realize they&amp;#8217;re giving us an image into cellular activity that is akin to a photograph from a cheap Soviet-era camera.&lt;/p&gt;

&lt;p&gt;Measuring gene expression from many cells glosses over interesting variation in each cell; this is certainly not a new complaint. However, even a &lt;em&gt;single&lt;/em&gt; cell image is messy: mRNAs that make their way into gene expression values may have never been exported from the nucleus, they could have been degraded by the cell, silenced, undergone post translational modification, etc. What&amp;#8217;s astounding is that these systems are not just complex, but are amazingly accurate. Cellular data is messy, but the cell certainly isn&amp;#8217;t. Development is a prime example of how tightly regulated these processes are. It&amp;#8217;s up to us to understand these tightly regulated systems with the messy images scientific data gives us. Machine learning is a necessary, but not sufficient tool to help us understand the cell.&lt;/p&gt;

&lt;p&gt;As an example, genes interact in groups, and many algorithms can gloss over this detail. If an algorithm tries to find a sparse set of genes that are biologically interesting to the problem at hand, it may be indifferent to which it includes from a set of co-expressed genes (consider the lasso against the elastic net here). If a biologist reviews these findings, they could easily miss something vastly important based on machine learning&amp;#8217;s indifference.&lt;/p&gt;

&lt;h2 id='lets_use_both'&gt;Let&amp;#8217;s Use Both.&lt;/h2&gt;

&lt;p&gt;These epiphanies are now what guides my path through biology and machine learning. I still love and am infatuated with machine learning (although, I much prefer the phrase statistical learning). However, if we wish to understand a complex system, we need to take the approach that modern biology does: leverage machine learning with &lt;em&gt;a priori&lt;/em&gt; biological expert knowledge to bootstrap findings. We need to design experiments that also harness the power of machine learning to help us &lt;em&gt;understand&lt;/em&gt;, and not just &lt;em&gt;predict&lt;/em&gt; the behavior of complex systems. Applied machine learners need to realize the power of experimental data. Chances are if you&amp;#8217;re finding everything you think is out there with just machine learning, you&amp;#8217;re making a mistake or your problem is too simple.&lt;/p&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>Elucidating k-mer Contamination with Kullback-Leibler Divergence</title>
    <link href="http://vincebuffalo.org/notes/2012/03/01/kmer-kl.html"/>
    <updated>2012-03-01T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/notes/2012/03/01/kmer-kl</id>
    <content type="html">&lt;h1 id='elucidating_kmer_contamination_with_kullbackleibler_divergence'&gt;Elucidating k-mer Contamination with Kullback-Leibler Divergence&lt;/h1&gt;

&lt;h2 id='severe_read_contamination'&gt;Severe Read Contamination&lt;/h2&gt;

&lt;p&gt;Recently a coworker showed me a FASTQ file from an Illumina HiSeq run (which will be packaged in the new release of my Bioconductor package &lt;a href='http://www.bioconductor.org/packages/release/bioc/html/qrqc.html'&gt;qrqc&lt;/a&gt;) that was severely contaminated. Below is the file in &lt;code&gt;less&lt;/code&gt; with a string highlighted:&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/less_contams.png' alt='A severely contaminated file in less, with many contaminants highlighted' /&gt;&lt;/p&gt;

&lt;p&gt;Holy contamination, Batman! There are a few approaches to handling this level of contamination. The program &lt;a href='http://www.ncbi.nlm.nih.gov/pubmed/19737799'&gt;tagdust&lt;/a&gt; will match contaminated reads and remove them. My program &lt;a href='github.com/vsbuffalo/scythe'&gt;Scythe&lt;/a&gt; is being changed so that it can match adapter contaminants further in the read using its Bayesian model. Both programs require &lt;em&gt;a priori&lt;/em&gt; knowledge of possible contamiant sequences - what if this is a novel sequence contaminant? In this case, &lt;code&gt;AAGCAGTGGTATCAACGCAGAGT&lt;/code&gt; appears to be a PCR primer related to DSN normalization that may not have made it into our adapter files.&lt;/p&gt;

&lt;h2 id='kmer_entropy_approaches'&gt;k-mer Entropy Approaches&lt;/h2&gt;

&lt;p&gt;k-mer approaches are a nice way of searching for such contaminants. I am currently adding this feature to &lt;code&gt;qrqc&lt;/code&gt;; you can follow development on the &lt;code&gt;kmer&lt;/code&gt; branch on &lt;a href='http://github.com/vsbuffalo/qrqc'&gt;Github&lt;/a&gt; but this branch may merge into master and disappear.&lt;/p&gt;

&lt;p&gt;The C functions I&amp;#8217;ve written use Heng Li&amp;#8217;s &lt;a href='http://attractivechaos.awardspace.com/khash.h.html'&gt;khash.h&lt;/a&gt; library to quickly hash k-mer sequences with their positions in the read. The end result is a data frame in R of k-mer sequence, position, and counts in that position.&lt;/p&gt;

&lt;p&gt;Looking at raw k-mer counts is somewhat useful, but I&amp;#8217;ve been exploring some information theoretical approaches to analyzing this data. One useful graphic is entropy of k-mers by position:&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/kmer_entropy.png' alt='k-mer entropy increasing by position in read' /&gt;&lt;/p&gt;

&lt;p&gt;These are 6-mers, so there are 4,096 possible k-mers (excluding N). If the k-mer distribution were uniform, 12 bits would be needed to encode each k-mer. This graph illustrates that even at the most random 3&amp;#8217;-end of the read, only about 6.5 bits are needed. In the first 20 bases, the distribution of k-mers is so skewed that less the Shannon entropy is less than four bits.&lt;/p&gt;

&lt;h2 id='kullbackleibler_divergence_approach'&gt;Kullback-Leibler Divergence Approach&lt;/h2&gt;

&lt;p&gt;It makes sense biologically that the k-mers don&amp;#8217;t have uniform frequency. In the case of read contaminants, the enrichment by position against an empirical k-mer distribution may be as interesting as total k-mer enrichment against a random distribution model.&lt;/p&gt;

&lt;p&gt;To assess this, some beta &lt;code&gt;qrqc&lt;/code&gt; code pools k-mer counts across position to find an empirical k-mer distribution. Then, the k-mer distribution per position is compared to the pooled distribution using the &lt;a href='http://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence'&gt;Kullback-Leibler divergence&lt;/a&gt;. K-L divergence is only defined when both distributions sum to 1, the sample spaces are the same, and if &lt;em&gt;q(i) &amp;gt; 0 for any i such that p(i)&amp;gt; 0&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In essence, the K-L divergence is measuring the average number of bits needed to encode data from &lt;em&gt;P&lt;/em&gt; with a code based on the distribution of &lt;em&gt;Q&lt;/em&gt;. In the k-mer case, &lt;em&gt;Q&lt;/em&gt; is the empirical distribution of k-mers irrespective of k-mer position and &lt;em&gt;P&lt;/em&gt; is the position-specific distribution of k-mers. Thus, an enrichment of k-mers at a particular position would lead to more divergence.&lt;/p&gt;

&lt;p&gt;A nice feature of &lt;code&gt;ggplot2&lt;/code&gt; is the stacking of the &amp;#8220;bar&amp;#8221; geom. Since K-L divergences are sums, stacking and setting fill color by k-mer (the terms of the sum) gives us a sense of the total divergence and each k-mer&amp;#8217;s effect on the total. There are too many k-mers to plot, so I have some procedures that find a nice subset. Because this is a subset, the K-L total (indicated by bar height) &lt;strong&gt;is wrong&lt;/strong&gt;, but the graphical interpretation is easier. Now, the enrichment by position is clear:&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/kl_kmer.png' alt='Kullback-Leibler divergence of k-mers' /&gt;&lt;/p&gt;

&lt;p&gt;This messy dataset has repeat primer contamination. Note that because we&amp;#8217;re plotting a &lt;em&gt;subset&lt;/em&gt; of k-mers, there is negative total K-L (not mathematically possible) because we&amp;#8217;re leaving out terms in the sum, but the meaning still comes through. Also note that there is k-mer nesting: The first wide peak begins with k-mer &lt;code&gt;TATCAA&lt;/code&gt;, then &lt;code&gt;ATCAAC&lt;/code&gt;, then &lt;code&gt;TCAACG&lt;/code&gt;, etc. This indicates that we could adjust k and find the entire repeated k-mer.&lt;/p&gt;

&lt;h2 id='update'&gt;Update&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ve added faceting of multiple &lt;code&gt;SequenceSummary&lt;/code&gt; objects&amp;#8217; KL/k-mer diagnostics. Combined with a random data file, this really illustrated contamination:&lt;/p&gt;
&lt;a href='/images/large_facet_kl.png'&gt;&lt;img src='/images/tiny_facet_kl.png' /&gt;&lt;/a&gt;
&lt;p&gt;This is still in development; follow the code on &lt;a href='http://github.com/vsbuffalo/qrqc'&gt;Github&lt;/a&gt; and feel free to contact me and make suggestions.&lt;/p&gt;</content>
  </entry>
  
  
  
  
  

  <entry>
    <title>Articles of Note, by Topic</title>
    <link href="http://vincebuffalo.org/notes/2012/02/23/articles.html"/>
    <updated>2012-02-23T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/notes/2012/02/23/articles</id>
    <content type="html">&lt;h1 id='articles_of_note_by_topic'&gt;Articles of Note, by Topic&lt;/h1&gt;

&lt;h2 id='gene_prediction'&gt;Gene prediction&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href='http://www.nature.com/nbt/journal/v25/n8/full/nbt0807-883.html'&gt;How does eukaryotic gene prediction work?&lt;/a&gt;&lt;/em&gt;, Brent, 2007.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='rnaseq'&gt;RNA-Seq&lt;/h2&gt;

&lt;h3 id='normalization'&gt;Normalization&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href='http://biostatistics.oxfordjournals.org/content/early/2012/01/24/biostatistics.kxr054.long'&gt;Removing technical variability in RNA-seq data using conditional quantile normalization&lt;/a&gt;&lt;/em&gt;, Hansen, 2011.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='biases'&gt;Biases&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href='http://genomebiology.com/2011/12/3/R22'&gt;Improving RNA-Seq expression estimates by correcting for fragment bias&lt;/a&gt;&lt;/em&gt;, Roberts et al., 2011&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='biological_networks'&gt;Biological Networks&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href='http://www.plospathogens.org/article/info%3Adoi%2F10.1371%2Fjournal.ppat.1001011#ppat.1001011-VanPoecke1'&gt;Network Modeling Reveals Prevalent Negative Regulatory Relationships between Signaling Sectors in Arabidopsis Immune Signaling&lt;/a&gt;&lt;/em&gt;, Sato et al, 2010.&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  
  
  
  
  

  <entry>
    <title>Please developers, don't be dicks.</title>
    <link href="http://vincebuffalo.org/essays/2012/02/21/dont-be-a-dick.html"/>
    <updated>2012-02-21T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/essays/2012/02/21/dont-be-a-dick</id>
    <content type="html">&lt;a title='Science is great, open it (open science) by mclapics, on
Flickr' href='http://www.flickr.com/photos/mclapics/6121420214/'&gt;&lt;img height='333' src='http://farm7.staticflickr.com/6188/6121420214_7f4fe7200a.jpg' width='500' alt='Science is great, open it (open
science)' /&gt;&lt;/a&gt;
&lt;h1 id='please_developers_dont_be_dicks'&gt;Please developers, don&amp;#8217;t be dicks.&lt;/h1&gt;

&lt;p&gt;As the author of a few open source tools, I&amp;#8217;ve had my fair share of users seeking help. Emails range from the very useful (bug reports, patches, etc) to the annoying (&amp;#8220;can you help guide me through this process&amp;#8221;). But never once (that I can remember) have I been a dick (and yes, I&amp;#8217;ve wanted to be). It will be tricky to write this without sounding self-righteous, but I hope to make the case that open source developers shouldn&amp;#8217;t be dicks in all cases.&lt;/p&gt;

&lt;h2 id='weve_all_been_there_wabt'&gt;We&amp;#8217;ve All Been There (WABT)&lt;/h2&gt;

&lt;p&gt;The first reason to never be a dick is that We&amp;#8217;ve All Been There (I&amp;#8217;m going to give this the acronym WABT). Even the most voracious and diligent manual readers can suffer from the &lt;a href='http://www.perlmonks.org/?node_id=542341'&gt;XY problem&lt;/a&gt;. A user comes asking how to do Y, which they think is the solution to X. However, it&amp;#8217;s a bad solution to X and they don&amp;#8217;t know this. These situations will always lead to frustration: users waste time explaining Y and helpers waste time explaining how to do Y to realize the user wanted X. But this is not the user&amp;#8217;s fault; it just takes programming practice to realize Y is not the correct way to do X.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve all had these problems in our early stages as developers. Being a dick in these cases will not help the user grok anything. They&amp;#8217;re already frustrated - that&amp;#8217;s why they&amp;#8217;re asking for your help. Being a dick will cause them to get more frustrated and &lt;em&gt;really&lt;/em&gt; not grasp anything. They&amp;#8217;re not going to have an &amp;#8220;ah ha!&amp;#8221; moment when they&amp;#8217;re too busy trying to come up with a witty response to your burn on IRC.&lt;/p&gt;

&lt;h2 id='pctm_has_the_same_number_of_letters_as_rtfm'&gt;PCTM has the same number of letters as RTFM&lt;/h2&gt;

&lt;p&gt;Please Check The Manual (PCTM) has the same number of letters as Read The Fucking Manual (RTFM). I strongly believe it takes more energy for a developer to be a dick than to be nice. We&amp;#8217;ve all had dumb questions that disrupt our workflow, make us angry, etc. But being a dick back does not discourage this behavior. Write some boilerplate text for responding to users&amp;#8217; questions. Make this a FAQ. Then respond, PCTM (Please Check the Manual) and send them the link. If they get needy, tell them open source software doesn&amp;#8217;t come with a warranty.&lt;/p&gt;

&lt;h2 id='people_remember_dicks'&gt;People remember dicks&lt;/h2&gt;

&lt;p&gt;Someone was once quite rude to me via email (I&amp;#8217;ll name him Tom). I had voiced some frustrations with software Tom wrote and he attacked me for these public comments. Now, as an aside, there&amp;#8217;s a lot of shitty software out there, and signals about software quality (even noisy signals) are &lt;em&gt;very valuable&lt;/em&gt;. Tom on one hand attacked me for saying something negative about his software, and on the other hand asked me to help fix it, emphasizing it was open source software. I agree with this sentiment 100%, however the email was clearly very angry.&lt;/p&gt;

&lt;p&gt;I told another developer who I&amp;#8217;ll call Jerry about the encounter, and he laughed. Apparently, Tom nagged Jerry about portability issues of Jerry&amp;#8217;s software years ago. This is evidence of my first point, WABT. It also shows that developers remember interactions with other developers &lt;em&gt;really&lt;/em&gt; well. Since then, I&amp;#8217;ve also heard other programmers complaining about interactions with Tom. This is all too bad, as Tom is probably very nice in person and certainly a good programmer.&lt;/p&gt;

&lt;h2 id='if_youre_a_dick_youre_hurting_oss'&gt;If you&amp;#8217;re a dick, you&amp;#8217;re hurting OSS&lt;/h2&gt;

&lt;p&gt;OSS has seen an explosion in recent years. Biologsts, ecologists, and social scientists that never thought they&amp;#8217;d write code are using R to analyze data. Folks frustrated by Windows are installing Ubuntu and asking for help. In the early days of the OSS, usenet, and IRC, it was an acceptable norm to be a dick. Now, it&amp;#8217;s not.&lt;/p&gt;

&lt;p&gt;OSS benefits from a large user base, but it will have growing pains. Being a dick does not alleviate these pains, it makes them worse. Let&amp;#8217;s go back to my story about Tom.&lt;/p&gt;

&lt;p&gt;In the second half of Tom&amp;#8217;s email (after attacking me), he asked me to help him fix his software. Now, collaboration can be difficult; code style clashes, merges fail, frustration is common. In a small project, you&amp;#8217;re really in bed with your collaborators. Now that Tom has sent me the signal he&amp;#8217;s nasty in correspondences, do you think I&amp;#8217;ll work on this project with him? Hell no. I&amp;#8217;d rather fork, fix the problem and encourage others to use my software. Of course this is bad for OSS; consider this passage from Eric S. Raymond&amp;#8217;s &lt;a href='http://catb.org/jargon/html/F/forked.html'&gt;Jargon File&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Forking is considered a Bad Thing - not merely because it implies a lot of wasted effort in the future, but because forks tend to be accompanied by a great deal of strife and acrimony between the successor groups over issues of legitimacy, succession, and design direction. There is serious social pressure against forking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tom&amp;#8217;s actions guarantee I will avoid working on his projects at all costs. The two other developers, and anyone else we&amp;#8217;ve told will too. In the end, the software loses.&lt;/p&gt;

&lt;h2 id='idolize_programmers_not_their_dickishness'&gt;Idolize programmers, not their dickishness&lt;/h2&gt;

&lt;p&gt;Some abrasive programmers are really gifted. Erik Naggum is regarded as the &lt;a href='http://en.wikipedia.org/wiki/Erik_Naggum#Controversy'&gt;first Usenet flamer&lt;/a&gt;. &lt;a href='http://en.wikipedia.org/wiki/Theo_de_raadt'&gt;Theo de Raadt&lt;/a&gt; forked NetBSD into what became OpenBSD partially because of issues with other developers. Richard Stallman gave an AMA on reddit a year ago and the &lt;a href='http://www.reddit.com/r/gnu/comments/c8rrk/rms_ama/'&gt;most popular question&lt;/a&gt; (since deleted) was about a young GNU-lover that was nervous about asking RMS a question and accidentally referred to it as &amp;#8220;Linux&amp;#8221;, not &amp;#8220;GNU/Linux&amp;#8221; and RMS ripped him in half.&lt;/p&gt;

&lt;p&gt;Now, all of these developers have been dickish and are well-known because they are gifted visionaries. I&amp;#8217;m not sure why, but other developers admire this dickishness. But don&amp;#8217;t idolize their dickishness, idolize their skill. There are also overwhelmingly nice programmers: &lt;a href='http://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)'&gt;John McCarthy&lt;/a&gt;, &lt;a href='http://en.wikipedia.org/wiki/Donald_Knuth'&gt;Donald Knuth&lt;/a&gt;, and &lt;a href='http://en.wikipedia.org/wiki/Alan_Turing'&gt;Alan Turing&lt;/a&gt; to name a few. Admire their skill &lt;em&gt;and&lt;/em&gt; their personality.&lt;/p&gt;

&lt;h2 id='being_a_dick_hurts_science'&gt;Being a dick hurts science&lt;/h2&gt;

&lt;p&gt;There&amp;#8217;s been an explosion of open source software utilization in the sciences. My field, bioinformatics, provides an interesting case study. There are bioinformaticians like myself that write software. Users are divided into other programmer types (other bioinformaticians) and biologists (on average, less knowledgeable of programming). All else equal, biologists and bioinformaticians prefer free, open source software to costly proprietary software.&lt;/p&gt;

&lt;p&gt;For these reasons, being helpful and nice to scientific users is really important. For biologists, choosing tools is about getting analysis done quickly and easily. Rude bioinformaticians will quickly increase the cost of using OSS tools, which is already high for many biologists who aren&amp;#8217;t experienced with Unix tools and programming. Consequently, science could become less open, something neither group wants.&lt;/p&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>Arduino Notes</title>
    <link href="http://vincebuffalo.org/notes/2012/02/21/arduino-notes.html"/>
    <updated>2012-02-21T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/notes/2012/02/21/arduino-notes</id>
    <content type="html">&lt;a title='Arduino UNO by Mr ATM, on Flickr' href='http://www.flickr.com/photos/nickhubbard/6468346201/'&gt;&lt;img height='333' src='http://farm8.staticflickr.com/7164/6468346201_b458451c53.jpg' width='500' alt='Arduino UNO' /&gt;&lt;/a&gt;
&lt;h1 id='arduino_notes'&gt;Arduino Notes&lt;/h1&gt;

&lt;p&gt;The following are some notes/links I&amp;#8217;ve come across when working with my Arduino Uno.&lt;/p&gt;

&lt;h2 id='arduino_development'&gt;Arduino Development&lt;/h2&gt;

&lt;p&gt;Ultimately I want to develop through Emacs, not the Arduino IDE. Doing this well involves (1) a good mode for Emacs, (2) interfacing with avr-gcc, and (3) a makefile or script that uploads the binary to the Arduino.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://github.com/bookest/arduino-mode'&gt;Emacs Arduino Mode&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.arduino.cc/en/Hacking/BuildProcess'&gt;The Arduino build process&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/takanuva/arduino-makefile'&gt;A nice makefile on Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='gps'&gt;GPS&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.sparkfun.com/tutorials/127'&gt;GPS buying guide (via Sparkfun)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='openlog'&gt;OpenLog&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.sparkfun.com/products/9530'&gt;OpenLog on SparkFun&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.sunshinehere.com/blog/?p=104'&gt;openLog and Arduino Uno interfacing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  
  
  

  <entry>
    <title>Hello, static blogging</title>
    <link href="http://vincebuffalo.org/notes/2012/02/20/another-post.html"/>
    <updated>2012-02-20T00:00:00-08:00</updated>
    <id>http://vincebuffalo.org/notes/2012/02/20/another-post</id>
    <content type="html">&lt;h1 id='why_static_blogging'&gt;Why static blogging?&lt;/h1&gt;

&lt;h2 id='simplicity'&gt;Simplicity&lt;/h2&gt;

&lt;p&gt;I spend hours each week in Emacs, and I&amp;#8217;ve spent &lt;a href='http://github.com/vsbuffalo/.emacs.d'&gt;ages customizing it&lt;/a&gt;. With &lt;a href='http://github.com/mojombo/jekyll'&gt;Jekll&lt;/a&gt;, &lt;a href='http://daringfireball.net/projects/markdown/syntax'&gt;Markdown&lt;/a&gt;, and &lt;a href='http://blueprintcss.org'&gt;Blueprint&lt;/a&gt; I quickly built this site in my favorite editor. I can spend time writing content, not fighting a browser WYSIWYG editor.&lt;/p&gt;

&lt;h2 id='mentality'&gt;Mentality&lt;/h2&gt;

&lt;p&gt;Also, I want this site to function as a notebook. Most blogging systems lead to a post-and-forget mentality. Revision control makes, well, revisions easier.&lt;/p&gt;

&lt;h2 id='plaintext'&gt;Plaintext&lt;/h2&gt;

&lt;p&gt;Plaintext is powerful (see &lt;a href='http://orgmode.org/'&gt;org-mode&lt;/a&gt; if you don&amp;#8217;t believe me). If I want to search all my posts using regular expressions, I can with &lt;code&gt;grep&lt;/code&gt;. How could this be done if I was using WordPress or any blogging system that used database backend?&lt;/p&gt;

&lt;h2 id='codefriendly'&gt;Code-friendly&lt;/h2&gt;

&lt;p&gt;Jekyll plays well with &lt;a href='http://pygments.org/'&gt;Pygments&lt;/a&gt;, a Python syntax highlighter. This is import because I want to share code.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='r'&gt;    &lt;span class='c1'&gt;# Jekyll is code friendly&lt;/span&gt;
    x &lt;span class='o'&gt;&amp;lt;-&lt;/span&gt; seq&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;-1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='m'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='m'&gt;0.1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    y &lt;span class='o'&gt;&amp;lt;-&lt;/span&gt; sin&lt;span class='p'&gt;(&lt;/span&gt;x&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; rnorm&lt;span class='p'&gt;(&lt;/span&gt;length&lt;span class='p'&gt;(&lt;/span&gt;x&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='m'&gt;0.3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    plot&lt;span class='p'&gt;(&lt;/span&gt;x&lt;span class='p'&gt;,&lt;/span&gt; y&lt;span class='p'&gt;)&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='formulae'&gt;Formulae&lt;/h2&gt;

&lt;p&gt;This was my final worry - org-mode is a bit &amp;#8220;heavy&amp;#8221; for publishing quick notes (although entirely necessary for other things), but it has excellent LaTeX integration. I would be very disappointed if I couldn&amp;#8217;t easily incorporate LaTeX into Jekyll. Luckily, I can! The default Maruku Markdown interpreter just needs to have LaTeX support turned on (see below)&amp;#8230; and wahla! I can include math:&lt;/p&gt;
&lt;div class='maruku-equation'&gt;&lt;img style='height: 5.44444444444444ex;' src='/images/latex/9b951c9f1142ca7692b66226bef9dec2.png' alt='$\widehat{\boldsymbol \theta}_{JS} = \left( 1 - \frac{(m-2)\sigma^2}{\|{\overline{\mathbf y}}\|^2} \right) {\overline{\mathbf y}}$' class='maruku-png' /&gt;&lt;span class='maruku-eq-tex'&gt;&lt;code style='display: none'&gt;\widehat{\boldsymbol \theta}_{JS} = \left( 1 - \frac{(m-2)\sigma^2}{\|{\overline{\mathbf y}}\|^2} \right) {\overline{\mathbf y}}&lt;/code&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h1 id='my_configuration'&gt;My configuration&lt;/h1&gt;

&lt;p&gt;There&amp;#8217;s a myriad of Ruby tools and plugins for Jekyll - it&amp;#8217;s all a bit intimidating. Here are a few notes on my configuration. &lt;a href='http://github.com/vsbuffalo/vsbuffalo.github.com/blob/master/_config.yml'&gt;My &lt;code&gt;_config.yml&lt;/code&gt; file is definitely important.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='maruku_and_latex'&gt;Maruku and LaTeX&lt;/h2&gt;

&lt;p&gt;I am using the default Markdown parser, Maruku. Maruku has formulae support, but it experimental and not on my default. Formulae are very important to my notebook, so getting them to work is paramount. Here&amp;#8217;s how I did it:&lt;/p&gt;

&lt;p&gt;1. Add the Maruku configurations below. Note the trailing slashes - these are important (and a sign that LaTeX support is still a bit rough.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;maruku:
  use_tex: true
  use_divs: true
  png_engine: blahtex
  png_dir: images/latex/
  png_url: /images/latex/&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;2. Install Xerces-C. On a Mac with MacPorts, use &lt;code&gt;sudo port install
  xercesc&lt;/code&gt;. This is a requirement for &lt;code&gt;blahtexml&lt;/code&gt;, which Maruku uses.&lt;/p&gt;

&lt;p&gt;3. Install &lt;code&gt;blahtexml&lt;/code&gt;. Get the source at &lt;a href='http://gva.noekeon.org/blahtexml'&gt;http://gva.noekeon.org/blahtexml&lt;/a&gt; and on a Mac, use &lt;code&gt;make
  blahtex-mac&lt;/code&gt; and put this binary in &lt;code&gt;/usr/local/bin/&lt;/code&gt; or some other place in your &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='pygments_and_blueprint_css'&gt;Pygments and Blueprint CSS&lt;/h2&gt;

&lt;p&gt;Blueprint CSS has a class &lt;code&gt;highlight&lt;/code&gt; in &lt;code&gt;screen.css&lt;/code&gt; that clashes with Pygment (giving code a hideous yellow background). I just renamed the class &lt;code&gt;highlight-alt&lt;/code&gt; in &lt;code&gt;screen.css&lt;/code&gt; and everything looks great now.&lt;/p&gt;

&lt;h2 id='build_errors_with_github'&gt;Build errors with Github&lt;/h2&gt;

&lt;p&gt;Github&amp;#8217;s Jekyll engine apparently runs with &lt;code&gt;jekyll --pygments --safe&lt;/code&gt; which disables plugins. LaTeX to PNG rendering is built into Maruku, not a plugin, yet builds still fail on Github (even though they are fine with these options locally). I also host this site at &lt;a href='http://vincebuffalo.org'&gt;http://vincebuffalo.org&lt;/a&gt;, so there&amp;#8217;s not a huge problem here.&lt;/p&gt;</content>
  </entry>
  
  
  
</feed>