diff --git a/normalize.cabal b/normalize.cabal
--- a/normalize.cabal
+++ b/normalize.cabal
@@ -1,13 +1,13 @@
 name:                normalize
-version:             0.3.0.1
+version:             0.3.1.0
 synopsis:            Normalize data using a variety of methods.
 description:         Normalize data using a variety of methods. For use with csv files.
 homepage:            http://github.com/GregorySchwartz/normalize#readme
 license:             GPL-3
 license-file:        LICENSE
 author:              Gregory W. Schwartz
-maintainer:          gsch@mail.med.upenn.edu
-copyright:           Copyright: (c) 2017 Gregory W. Schwartz
+maintainer:          gsch@pennmedicine.upenn.edu
+copyright:           Copyright: (c) 2018 Gregory W. Schwartz
 category:            Bioinformatics
 build-type:          Simple
 -- extra-source-files:
@@ -19,13 +19,15 @@
                      , Load
                      , Normalize
                      , Filter
+                     , Utility
   build-depends:       base >= 4.7 && < 5
+                     , cassava
                      , containers
                      , lens
-                     , vector
-                     , text
-                     , cassava
+                     , sparse-linear-algebra
                      , statistics
+                     , text
+                     , vector
   ghc-options:         -O2
   default-language:    Haskell2010
 
@@ -35,12 +37,12 @@
   ghc-options:         -threaded -rtsopts -O2
   build-depends:       base
                      , normalize
-                     , optparse-generic
-                     , containers
-                     , vector
                      , bytestring
-                     , text
                      , cassava
+                     , containers
+                     , optparse-generic
+                     , text
+                     , vector
   default-language:    Haskell2010
 
 source-repository head
diff --git a/src/Normalize.hs b/src/Normalize.hs
--- a/src/Normalize.hs
+++ b/src/Normalize.hs
@@ -25,14 +25,16 @@
 import Data.Function (on)
 
 -- Cabal
-import qualified Data.Vector as V
-import qualified Data.Text as T
+import Control.Lens
 import Statistics.Quantile
+import qualified Data.Sparse.Common as S
+import qualified Data.Text as T
+import qualified Data.Vector as V
 import qualified Statistics.Sample as Stat
-import Control.Lens
 
 -- Local
 import Types
+import Utility
 
 -- | Log transform the normalize map.
 logTransform :: Base -> Map.Map Sample (V.Vector Entity) -> Map.Map Sample (V.Vector Entity)
@@ -52,7 +54,15 @@
 normalize StandardScore = Map.map standardScore
 normalize UpperQuartile = Map.map upperQuartileNormalize
 normalize None          = id
+normalize _             = error "Method not supported by normalize."
 
+-- | Normalize all samples by a specific method using a sparse matrix.
+normalizeSparse :: Method -> S.SpMatrix Double -> S.SpMatrix Double
+normalizeSparse method@QuantileMedian  = quantileNormalize method
+normalizeSparse method@QuantileAverage = quantileNormalize method
+normalizeSparse None            = id
+normalizeSparse _ = error "Method not supported by normalizeSparse."
+
 -- | Normalize a sample (1) by another sample (2) by division. The
 -- NormSampleString contains the string that differentiates (1) from (2).
 -- NormSampleString must be within (2) and must make, upon its removal from (2),
@@ -145,3 +155,16 @@
   where
     zeroFiltered = V.filter ((> 0) . _value) xs
     uqVal = continuousBy (ContParam 1 1) 3 4 . fmap _value
+
+-- | Quantile normalization for sparse matrices, ignoring zeros.
+quantileNormalize :: Method -> S.SpMatrix Double -> S.SpMatrix Double
+quantileNormalize method mat =
+    fmap (\x -> S.lookupDenseSV (x - 1) summaryVec) rankMat
+  where
+    summaryFunc QuantileMedian  = medianSparseVector
+    summaryFunc QuantileAverage = avgSparseVector
+    summaryFunc _ = error "Unsupported method for quantile normalization."
+    summaryVec =
+        S.sparsifySV . S.vr . fmap (summaryFunc method) . S.toRowsL $ sortMat
+    sortMat    = S.fromColsL . fmap sortSparseVector . S.toColsL $ mat
+    rankMat    = S.fromColsL . fmap rankSparseVector . S.toColsL $ mat
diff --git a/src/Types.hs b/src/Types.hs
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -40,7 +40,12 @@
 -- Advanced
 
 -- Algebraic
-data Method = StandardScore | UpperQuartile | None deriving (Eq, Read, Show)
+data Method = StandardScore
+            | UpperQuartile
+            | QuantileMedian
+            | QuantileAverage
+            | None
+            deriving (Eq, Read, Show)
 
 data Entity = Entity
                 { _label      :: !T.Text
diff --git a/src/Utility.hs b/src/Utility.hs
new file mode 100644
--- /dev/null
+++ b/src/Utility.hs
@@ -0,0 +1,55 @@
+{- Utility
+Gregory W. Schwartz
+
+Collections helper functions for the program.
+-}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Utility
+    ( sortSparseVector
+    , rankSparseVector
+    , medianSparseVector
+    , avgSparseVector
+    ) where
+
+-- Standard
+import Data.Function (on)
+import Data.List
+
+-- Cabal
+import Control.Lens
+import Statistics.Quantile
+import Statistics.Sample (mean)
+import qualified Data.Map.Strict as Map
+import qualified Data.Set as Set
+import qualified Data.Sparse.Common as S
+import qualified Data.Vector.Unboxed as V
+
+-- Local
+
+-- | Find the average of a sparse vector, ignoring zeros.
+avgSparseVector :: S.SpVector Double -> Double
+avgSparseVector xs = mean . V.fromList . fmap snd . S.toListSV $ xs
+
+-- | Find the median of a sparse vector, ignoring zeros.
+medianSparseVector :: S.SpVector Double -> Double
+medianSparseVector xs =
+    continuousBy s 2 4 . V.fromList . fmap snd . S.toListSV $ xs
+
+-- | Sort a sparse vector, ignoring zeros.
+sortSparseVector :: S.SpVector Double -> S.SpVector Double
+sortSparseVector xs =
+    S.fromListDenseSV (S.svDim xs) . sort . fmap snd . S.toListSV $ xs
+
+-- | Get the rank transformed vector of a sparse vector, ignoring zeros.
+rankSparseVector :: S.SpVector Double -> S.SpVector Int
+rankSparseVector xs = fmap (\k -> Map.findWithDefault 0 k rankMap) xs
+  where
+    rankMap = Map.fromList
+            . flip zip [1,2..]
+            . Set.toList
+            . Set.fromList
+            . fmap snd
+            . S.toListSV
+            $ xs
