packages feed

datasets 0.2.2 → 0.2.3

raw patch · 8 files changed

+99/−56 lines, 8 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Numeric.Datasets: parseCSV :: FromRecord a => (ByteString -> ByteString) -> ByteString -> [a]
- Numeric.Datasets: parseCSVHdr :: FromNamedRecord a => ByteString -> [a]
- Numeric.Datasets: parseCSVHdrSep :: FromNamedRecord a => Char -> ByteString -> [a]
- Numeric.Datasets: parseJSON :: FromJSON a => ByteString -> [a]
- Numeric.Datasets: type Dataset a = FilePath Directory for caching downloaded datasets -> IO [a]
+ Numeric.Datasets: Dataset :: Source -> Maybe FilePath -> Maybe (ByteString -> ByteString) -> ReadAs a -> Dataset a
+ Numeric.Datasets: [CSVNamedRecord] :: FromNamedRecord a => DecodeOptions -> ReadAs a
+ Numeric.Datasets: [CSVRecord] :: FromRecord a => HasHeader -> DecodeOptions -> ReadAs a
+ Numeric.Datasets: [JSON] :: FromJSON a => ReadAs a
+ Numeric.Datasets: [preProcess] :: Dataset a -> Maybe (ByteString -> ByteString)
+ Numeric.Datasets: [readAs] :: Dataset a -> ReadAs a
+ Numeric.Datasets: [source] :: Dataset a -> Source
+ Numeric.Datasets: [temporaryDirectory] :: Dataset a -> Maybe FilePath
+ Numeric.Datasets: csvRecord :: FromRecord a => ReadAs a
+ Numeric.Datasets: data Dataset a
+ Numeric.Datasets: data ReadAs a
+ Numeric.Datasets: readDataset :: ReadAs a -> ByteString -> [a]
+ Numeric.Datasets.Coal: coal :: Dataset Coal
+ Numeric.Datasets.Coal: data Coal
+ Numeric.Datasets.Coal: date :: Coal -> Double
+ Numeric.Datasets.Coal: instance Data.Csv.Conversion.FromRecord Numeric.Datasets.Coal.Coal
+ Numeric.Datasets.Coal: instance GHC.Generics.Generic Numeric.Datasets.Coal.Coal
+ Numeric.Datasets.Coal: instance GHC.Read.Read Numeric.Datasets.Coal.Coal
+ Numeric.Datasets.Coal: instance GHC.Show.Show Numeric.Datasets.Coal.Coal
+ Numeric.Datasets.Iris: instance GHC.Classes.Ord Numeric.Datasets.Iris.IrisClass
+ Numeric.Datasets.OldFaithful: instance GHC.Show.Show Numeric.Datasets.OldFaithful.OldFaithful

Files

changelog.md view
@@ -1,3 +1,11 @@+0.2.3++* Coal dataset++* New internal API++* Ord instance for IrisClass+ 0.2.2  * Enum, bounded instances for IrisClass
datasets.cabal view
@@ -1,5 +1,5 @@ Name:                datasets-Version:             0.2.2+Version:             0.2.3 Synopsis:            Classical data sets for statistics and machine learning Description:         Classical machine learning and statistics datasets from                      the UCI Machine Learning Repository and other sources.@@ -59,6 +59,7 @@                  , Numeric.Datasets.Adult                  , Numeric.Datasets.BreastCancerWisconsin                  , Numeric.Datasets.Car+                 , Numeric.Datasets.Coal                  , Numeric.Datasets.CO2                  , Numeric.Datasets.Gapminder                  , Numeric.Datasets.Iris
src/Numeric/Datasets.hs view
@@ -16,7 +16,7 @@  -} -{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, GADTs #-}  module Numeric.Datasets where @@ -27,7 +27,7 @@ import Data.Monoid import qualified Data.ByteString.Lazy as BL import qualified Data.Vector as V-import qualified Data.Aeson as JSON+import Data.Aeson as JSON import Control.Applicative import Data.Time import Data.Char (ord)@@ -36,6 +36,7 @@  import Data.Char (toUpper) import Text.Read (readMaybe)+import Data.Maybe (fromMaybe) import Data.ByteString.Char8 (unpack) import qualified Data.ByteString.Lazy.Char8 as BL8 import Data.ByteString.Lazy.Search (replace)@@ -45,41 +46,72 @@ -- |Load a dataset, using the system temporary directory as a cache getDataset :: Dataset a -> IO [a] getDataset ds = do-  dir <- getTemporaryDirectory-  ds $ dir </> "haskds"---- | A dataset is defined as a function from the caching directory to the IO action that loads the data-type Dataset a = FilePath -- ^ Directory for caching downloaded datasets-                 -> IO [a]+  dir <- case temporaryDirectory ds of+           Nothing -> getTemporaryDirectory+           Just tdir -> return tdir+  bs <- fmap (fromMaybe id $ preProcess ds) $ getFileFromSource dir $ source ds+  return $ readDataset (readAs ds) bs --- * Defining datasets+-- |Read a ByteString into a Haskell value+readDataset :: ReadAs a -> BL.ByteString -> [a]+readDataset JSON bs =+  case JSON.decode bs of+    Just theData ->  theData+    Nothing -> error "failed to parse json"+readDataset (CSVRecord hhdr opts) bs =+  case decodeWith opts hhdr bs of+    Right theData -> V.toList theData+    Left err -> error err+readDataset (CSVNamedRecord opts) bs =+  case decodeByNameWith opts bs of+    Right (_,theData) -> V.toList theData+    Left err -> error err  data Source = URL String +-- | A dataset is a record telling us how to load the data++data Dataset a = Dataset+  { source :: Source+  , temporaryDirectory :: Maybe FilePath+  , preProcess :: Maybe (BL.ByteString -> BL.ByteString)+  , readAs :: ReadAs a+  }++-- | ReadAs is a datatype to describe data formats that hold data sets++data ReadAs a where+  JSON :: FromJSON a => ReadAs a+  CSVRecord :: FromRecord a => HasHeader -> DecodeOptions -> ReadAs a+  CSVNamedRecord :: FromNamedRecord a => DecodeOptions -> ReadAs a++csvRecord :: FromRecord a => ReadAs a+csvRecord = CSVRecord NoHeader defaultDecodeOptions++-- * Defining datasets+ -- |Define a dataset from a pre-processing function and a source for a CSV file csvDatasetPreprocess :: FromRecord a => (BL.ByteString -> BL.ByteString) -> Source -> Dataset a-csvDatasetPreprocess preF src cacheDir = do-  parseCSV preF <$> getFileFromSource cacheDir src+csvDatasetPreprocess preF src = (csvDataset src) { preProcess = Just preF }+--  parseCSV preF <$> getFileFromSource cacheDir src  -- |Define a dataset from a source for a CSV file csvDataset :: FromRecord a =>  Source -> Dataset a-csvDataset  = csvDatasetPreprocess id+csvDataset src = Dataset src Nothing Nothing $ CSVRecord NoHeader defaultDecodeOptions  -- |Define a dataset from a source for a CSV file with a known header csvHdrDataset :: FromNamedRecord a => Source -> Dataset a-csvHdrDataset src cacheDir = do-  parseCSVHdr <$> getFileFromSource cacheDir src+csvHdrDataset src = Dataset src Nothing Nothing $ CSVNamedRecord defaultDecodeOptions  -- |Define a dataset from a source for a CSV file with a known header and separator csvHdrDatasetSep :: FromNamedRecord a => Char -> Source -> Dataset a-csvHdrDatasetSep sepc src cacheDir = do-  parseCSVHdrSep sepc <$> getFileFromSource cacheDir src+csvHdrDatasetSep sepc src+   = Dataset src Nothing Nothing+       $ CSVNamedRecord defaultDecodeOptions { decDelimiter = fromIntegral (ord sepc)}  -- |Define a dataset from a source for a JSON file -- data file must be accessible with HTTP, not HTTPS-jsonDataset :: JSON.FromJSON a => Source -> Dataset a-jsonDataset src cacheDir = do-  bs <- getFileFromSource cacheDir src-  return $ parseJSON bs+jsonDataset :: FromJSON a => Source -> Dataset a+jsonDataset src = Dataset src Nothing Nothing JSON  -- | Get a ByteString from the specified Source getFileFromSource :: FilePath -> Source -> IO (BL.ByteString)@@ -95,36 +127,6 @@        let bs = rsp ^. Wreq.responseBody        BL.writeFile fnm bs        return bs---- | Parse CSV file-parseCSV :: FromRecord a => (BL.ByteString -> BL.ByteString) -> BL.ByteString -> [a]-parseCSV preF contents =-        case decode NoHeader (preF contents) of-          Right theData -> V.toList theData-          Left err -> error err---- | Parse CSV file with known header-parseCSVHdr :: FromNamedRecord a => BL.ByteString -> [a]-parseCSVHdr contents =-        case decodeByName contents of-          Right (_,theData) -> V.toList theData-          Left err -> error err---- | Parse CSV file with known header-parseCSVHdrSep :: FromNamedRecord a => Char -> BL.ByteString -> [a]-parseCSVHdrSep sepc contents =-        let opts = defaultDecodeOptions { decDelimiter = fromIntegral (ord sepc)} in-        case decodeByNameWith opts contents of-          Right (_,theData) -> V.toList theData-          Left err -> error err---- | Parse JSON file-parseJSON :: JSON.FromJSON a => BL.ByteString -> [a]-parseJSON bs = case JSON.decode bs of-  Just theData ->  theData-  Nothing -> error "failed to parse json"--  -- * Helper functions for parsing 
+ src/Numeric/Datasets/Coal.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE DeriveGeneric, OverloadedStrings                   #-}+{-# LANGUAGE GADTs, QuasiQuotes, ViewPatterns, FlexibleContexts #-}++{-|++Coal data set++Dates of mining disasters, from the `coal` dataset in the R package `boot`.++For further information, see <http://vincentarelbundock.github.io/Rdatasets/doc/boot/coal.html>++-}++module Numeric.Datasets.Coal ( Coal, coal, date ) where++import Numeric.Datasets++import Data.Csv+import GHC.Generics+import Control.Applicative++data Coal = Coal+  { date :: Double+  } deriving (Show, Read, Generic)++instance FromRecord Coal where+  parseRecord v = Coal <$> v .! 1++coal :: Dataset Coal+coal = let src = URL "http://vincentarelbundock.github.io/Rdatasets/csv/boot/coal.csv"+       in Dataset src Nothing Nothing $ CSVRecord HasHeader defaultDecodeOptions
src/Numeric/Datasets/Iris.hs view
@@ -19,7 +19,7 @@   data IrisClass = Setosa | Versicolor | Virginica-  deriving (Show, Read, Eq, Generic, Enum, Bounded)+  deriving (Show, Read, Eq, Ord, Generic, Enum, Bounded)  instance FromField IrisClass where   parseField "Iris-setosa" = return Setosa@@ -38,4 +38,4 @@ instance FromRecord Iris  iris :: [Iris]-iris = parseCSV id $ fromStrict $(embedFile "datafiles/iris.data")+iris = readDataset csvRecord (fromStrict $(embedFile "datafiles/iris.data"))
src/Numeric/Datasets/Michelson.hs view
@@ -18,4 +18,4 @@   michelson :: [[Double]]-michelson = parseJSON $ fromStrict $(embedFile "datafiles/michelson.json")+michelson = readDataset JSON (fromStrict $(embedFile "datafiles/michelson.json"))
src/Numeric/Datasets/Nightingale.hs view
@@ -31,4 +31,4 @@ instance FromJSON Nightingale  nightingale :: [Nightingale]-nightingale = parseJSON $ fromStrict $(embedFile "datafiles/nightingale.json")+nightingale = readDataset JSON $ fromStrict $(embedFile "datafiles/nightingale.json")
src/Numeric/Datasets/OldFaithful.hs view
@@ -18,7 +18,8 @@   { recordingDay :: Int -- ^ Recording day. 1-8: 1978, 16-23: 1979   , waiting :: Double -- ^ waiting time until next eruption   , duration :: Double -- ^ duration of eruption in minutes-  }+  } deriving Show+ -- The first comp oldFaithful :: [OldFaithful] oldFaithful =