rank-product 0.2.0.1 → 0.2.1.0
raw patch · 5 files changed
+172/−3 lines, 5 filesdep +bytestringdep +cassavadep +containersdep ~basenew-component:exe:rank-productPVP ok
version bump matches the API change (PVP)
Dependencies added: bytestring, cassava, containers, lens, optparse-generic, rank-product, text, vector
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Statistics.Load: loadNamedEntities :: Vector (Map Text Text) -> [NamedEntity]
+ Statistics.RankProduct: namedRankProductPermutation :: Permutations -> Sort -> [NamedEntity] -> IO [(Name, RankProductEntity, PValue)]
+ Statistics.Types: Delimiter :: Char -> Delimiter
+ Statistics.Types: Name :: Text -> Name
+ Statistics.Types: NamedEntity :: Name -> [Double] -> NamedEntity
+ Statistics.Types: [name] :: NamedEntity -> Name
+ Statistics.Types: [unDelimiter] :: Delimiter -> Char
+ Statistics.Types: [unName] :: Name -> Text
+ Statistics.Types: [values] :: NamedEntity -> [Double]
+ Statistics.Types: data NamedEntity
+ Statistics.Types: instance GHC.Classes.Eq Statistics.Types.Name
+ Statistics.Types: instance GHC.Classes.Ord Statistics.Types.Name
+ Statistics.Types: instance GHC.Read.Read Statistics.Types.Delimiter
+ Statistics.Types: instance GHC.Show.Show Statistics.Types.Delimiter
+ Statistics.Types: instance GHC.Show.Show Statistics.Types.Name
+ Statistics.Types: instance GHC.Show.Show Statistics.Types.NamedEntity
+ Statistics.Types: instance GHC.Show.Show Statistics.Types.Permutations
+ Statistics.Types: newtype Delimiter
+ Statistics.Types: newtype Name
Files
- app/Main.hs +81/−0
- rank-product.cabal +19/−1
- src/Statistics/Load.hs +43/−0
- src/Statistics/RankProduct.hs +18/−1
- src/Statistics/Types.hs +11/−1
+ app/Main.hs view
@@ -0,0 +1,81 @@+{- rank-product+Gregory W. Schwartz++Get the rank product of a data frame.+-}++{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeOperators #-}++module Main where++-- Remote+import Data.Char (ord)+import Data.Maybe (fromMaybe)+import Options.Generic+import qualified Control.Lens as L+import qualified Data.ByteString.Lazy.Char8 as B+import qualified Data.Csv as CSV++-- Local+import Statistics.Types+import Statistics.Load+import Statistics.RankProduct++-- | Command line arguments+data Options = Options { permutations :: Maybe Int+ <?> "([1000] | INT) Number of permutations for rank product p-value."+ , delimiter :: Maybe Char+ <?> "([,] | CHAR) The delimiter of the CSV file. Format is name,replicate,value."+ , sortType :: Maybe Sort+ <?> "([Ascending] | Descending) How to sort for output."+ }+ deriving (Generic)++modifiers :: Modifiers+modifiers = lispCaseModifiers { shortNameModifier = short }+ where+ short x = firstLetter x++instance ParseField Sort++instance ParseRecord Options where+ parseRecord = parseRecordWithModifiers modifiers++main :: IO ()+main = do+ opts <- getRecord "rank-product, Gregory W. Schwartz.\+ \ Compute the rank product for a data frame.\+ \ Format is name,replicate,value."++ let permutations' =+ Permutations . fromMaybe 1000 . unHelpful . permutations $ opts+ delim' =+ Delimiter . fromMaybe ',' . unHelpful . delimiter $ opts+ sortType' = fromMaybe Ascending . unHelpful . sortType $ opts+ decodeOpt = CSV.defaultDecodeOptions+ { CSV.decDelimiter =+ fromIntegral (ord . unDelimiter $ delim')+ }+ encodeOpt = CSV.defaultEncodeOptions+ { CSV.encDelimiter =+ fromIntegral (ord . unDelimiter $ delim')+ }++ entities <- loadNamedEntities+ . either error snd+ . CSV.decodeByNameWith decodeOpt+ <$> B.getContents++ rankedEntities <-+ namedRankProductPermutation permutations' sortType' entities++ let header = "name,rank,pvalue\n"+ body = L.over L._3 unPValue+ . L.over L._2 unRankProductEntity+ . L.over L._1 unName+ <$> rankedEntities++ B.putStrLn . (header <>) $ CSV.encodeWith encodeOpt body
rank-product.cabal view
@@ -1,5 +1,5 @@ name: rank-product-version: 0.2.0.1+version: 0.2.1.0 synopsis: Find the rank product of a data set. description: Find the rank product of a data set and get the p-value from a permutation test. homepage: http://github.com/GregorySchwartz/rank-product#readme@@ -16,10 +16,28 @@ library hs-source-dirs: src exposed-modules: Statistics.Types+ , Statistics.Load , Statistics.RankProduct build-depends: base >= 4.7 && < 5+ , containers , random-fu+ , text+ , vector ghc-options: -O2+ default-language: Haskell2010++executable rank-product+ hs-source-dirs: app+ main-is: Main.hs+ ghc-options: -threaded -rtsopts -O2+ build-depends: base+ , optparse-generic+ , rank-product+ , bytestring+ , cassava+ , containers+ , lens+ , vector default-language: Haskell2010 source-repository head
+ src/Statistics/Load.hs view
@@ -0,0 +1,43 @@+{- Load+Gregory W. Schwartz++Collects the functions pertaining to loading the data frame from rows of a file.+-}++{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE OverloadedStrings #-}++module Statistics.Load+ ( loadNamedEntities+ ) where++-- Standard+import Data.List (sort)+import qualified Data.Foldable as F+import qualified Data.Map.Strict as Map+import qualified Data.Sequence as Seq+import qualified Data.Text as T+import qualified Data.Text.Read as T+import qualified Data.Vector as V++-- Cabal++-- Local+import Statistics.Types++-- | Load entities from a list of rows.+loadNamedEntities :: V.Vector (Map.Map T.Text T.Text) -> [NamedEntity]+loadNamedEntities = fmap (uncurry NamedEntity)+ . Map.toAscList+ . Map.map (fmap snd . sort . F.toList)+ . Map.fromListWith (Seq.><)+ . fmap lookupInfo+ . V.toList+ where+ lookupErr x = Map.findWithDefault (error $ "Missing column: " <> show x) x+ lookupInfo m =+ ( Name $ lookupErr "name" m+ , Seq.singleton ( lookupErr "replicate" m+ , either error fst . T.double $ lookupErr "value" m+ )+ )
src/Statistics/RankProduct.hs view
@@ -12,6 +12,7 @@ , rankProduct , prerankProduct , rankProductPermutation+ , namedRankProductPermutation ) where -- Standard@@ -19,7 +20,6 @@ import Data.List import Data.Random - -- Cabal -- Local@@ -112,3 +112,20 @@ fmap (\e -> PValue $ (fromIntegral e) / (fromIntegral permutations)) exp return . zip obs $ pVals++-- | Get the rank product of a list of NamedEntity as well as the permutation+-- p-value, removing entities without all replicates. Ascending ranks the lowest+-- value as 1 while Descending ranks the highest value as 1.+namedRankProductPermutation :: Permutations+ -> Sort+ -> [NamedEntity]+ -> IO [(Name, RankProductEntity, PValue)]+namedRankProductPermutation permutations sortType entities =+ fmap (zipWith (\ !n (!r, !p) -> (n, r, p)) names)+ . rankProductPermutation permutations sortType+ . fmap (\(NamedEntity _ xs) -> Entity xs)+ . filter ((== maxReplicates) . length . values)+ $ entities+ where+ names = fmap name entities+ maxReplicates = maximum . fmap (length . values) $ entities
src/Statistics/Types.hs view
@@ -4,9 +4,12 @@ Collects the types used in the program -} +{-# LANGUAGE StrictData #-}+ module Statistics.Types where -- Standard+import qualified Data.Text as T -- Cabal @@ -14,7 +17,9 @@ -- Basic-newtype Permutations = Permutations Int+newtype Delimiter = Delimiter { unDelimiter :: Char } deriving (Read, Show)+newtype Name = Name { unName :: T.Text } deriving (Eq, Ord, Show)+newtype Permutations = Permutations Int deriving (Show) newtype Entity = Entity { unEntity :: [Double] } deriving (Show) newtype RankEntity = RankEntity { unRankEntity :: [Double] } deriving (Show) newtype RankProductEntity = RankProductEntity@@ -24,3 +29,8 @@ -- Advanced data Sort = Ascending | Descending deriving (Eq, Ord, Read, Show)++data NamedEntity = NamedEntity { name :: Name+ , values :: [Double]+ }+ deriving (Show)