packages feed

dataframe-0.3.0.0: examples/Chipotle.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications  #-}
module Main where

import qualified DataFrame as D
import qualified DataFrame.Functions as F
import qualified Data.Text as T

import DataFrame ((|>))

main :: IO ()
main = do
  raw <- D.readTsv "./data/chipotle.tsv"
  print $ D.dimensions raw

  -- -- Sampling the dataframe
  print $ D.take 5 raw

  -- Transform the data from a raw string into
  -- respective types (throws error on failure)
  let df =
        raw
          -- Change a specfic order ID
          |> D.applyWhere (== (1 ::Int)) "order_id" (+ (2 :: Int)) "quantity"
          -- Index based change.
          |> D.applyAtIndex 0 ((\n -> n - 2) :: Int -> Int) "quantity"
          -- Custom parsing: drop dollar sign and parse price as double
          |> D.apply (D.readValue @Double . T.drop 1) "item_price"

  -- sample the dataframe.
  print $ D.take 10 df

  -- Create a total_price column that is quantity * item_price
  let withTotalPrice = D.derive "total_price" (F.lift fromIntegral (F.col @Int "quantity") * F.col @Double"item_price") df

  -- sample a filtered subset of the dataframe
  putStrLn "Sample dataframe"
  print $
    withTotalPrice
      |> D.select ["quantity", "item_name", "item_price", "total_price"]
      |> D.filter "total_price" ((100.0 :: Double) <)
      |> D.take 10

  -- Check how many chicken burritos were ordered.
  -- There are two ways to checking how many chicken burritos
  -- were ordered.
  let searchTerm = "Chicken Burrito" :: T.Text

  print $
    df
      |> D.select ["item_name", "quantity"]
      -- It's more efficient to filter before grouping.
      |> D.filter "item_name" (searchTerm ==)
      |> D.groupBy ["item_name"]
      |> D.aggregate [ (F.sum (F.col @Int "quantity"))     `F.as` "sum"
                     , (F.maximum (F.col @Int "quantity")) `F.as` "max"
                     , (F.mean (F.col @Int "quantity"))    `F.as` "mean"]
      |> D.sortBy D.Descending ["sum"]

  -- Similarly, we can aggregate quantities by all rows.
  print $
    df
      |> D.select ["item_name", "quantity"]
      |> D.groupBy ["item_name"]
      |> D.aggregate [ (F.sum (F.col @Int "quantity"))     `F.as` "sum"
                     , (F.maximum (F.col @Int "quantity")) `F.as` "maximum"
                     , (F.mean (F.col @Int "quantity"))    `F.as` "mean"]
      |> D.take 10

  let firstOrder =
        withTotalPrice
          |> D.filterBy (maybe False (T.isInfixOf "Guacamole")) "choice_description"
          |> D.filterBy (("Chicken Bowl" :: T.Text) ==) "item_name"

  print $ D.take 10 firstOrder