{-# LANGUAGE OverloadedStrings #-} module Operations.Merge where import qualified DataFrame as D import qualified DataFrame.Internal.Column as DI import DataFrame.Operations.Merge ((|||)) import Test.HUnit df1 :: D.DataFrame df1 = D.fromNamedColumns [ ("A", DI.fromList [1 :: Int, 2]) , ("B", DI.fromList ['a', 'b']) ] df2 :: D.DataFrame df2 = D.fromNamedColumns [ ("A", DI.fromList [3 :: Int]) , ("B", DI.fromList ['c']) ] dfOnlyA :: D.DataFrame dfOnlyA = D.fromNamedColumns [("A", DI.fromList [1 :: Int, 2])] dfOnlyB :: D.DataFrame dfOnlyB = D.fromNamedColumns [("B", DI.fromList ['c', 'd'])] dfSide1 :: D.DataFrame dfSide1 = D.fromNamedColumns [("L", DI.fromList [10 :: Int, 20])] dfSide2 :: D.DataFrame dfSide2 = D.fromNamedColumns [("R", DI.fromList ["x" :: String, "y"])] mergeVerticalWAI :: Test mergeVerticalWAI = TestCase ( assertEqual "Vertical merge concatenates matching columns" ( D.fromNamedColumns [ ("A", DI.fromList [1 :: Int, 2, 3]) , ("B", DI.fromList ['a', 'b', 'c']) ] ) (df1 <> df2) ) mergeVerticalDisjointSchemas :: Test mergeVerticalDisjointSchemas = TestCase ( assertEqual "Disjoint schemas produce optional padding" ( D.fromNamedColumns [ ( "A" , DI.fromList [ Just (1 :: Int) , Just 2 , Nothing , Nothing ] ) , ( "B" , DI.fromList [ Nothing , Nothing , Just 'c' , Just 'd' ] ) ] ) (dfOnlyA <> dfOnlyB) ) mergeVerticalWithEmptyLeft :: Test mergeVerticalWithEmptyLeft = TestCase ( assertEqual "Empty <> df = df" df1 (D.empty <> df1) ) mergeVerticalWithEmptyRight :: Test mergeVerticalWithEmptyRight = TestCase ( assertEqual "df <> Empty = df" df1 (df1 <> D.empty) ) mergeHorizontalWAI :: Test mergeHorizontalWAI = TestCase ( assertEqual "Horizontal merge combines columns side by side" ( D.fromNamedColumns [ ("L", DI.fromList [10 :: Int, 20]) , ("R", DI.fromList ["x" :: String, "y"]) ] ) (dfSide1 ||| dfSide2) ) mergeHorizontalWithEmptyRight :: Test mergeHorizontalWithEmptyRight = TestCase ( assertEqual "df ||| empty = df" dfSide1 (dfSide1 ||| D.empty) ) mergeHorizontalWithEmptyLeft :: Test mergeHorizontalWithEmptyLeft = TestCase ( assertEqual "empty ||| df = df" dfSide2 (D.empty ||| dfSide2) ) mergeVerticalDifferentTypesSameColumnName :: Test mergeVerticalDifferentTypesSameColumnName = let dfIntA = D.fromNamedColumns [("A", DI.fromList [1 :: Int, 2])] dfTextA = D.fromNamedColumns [("A", DI.fromList ["x" :: String, "y"])] in TestCase ( assertEqual "Merging columns with same name but different types wraps the values in Either" ( D.fromNamedColumns [ ("A", DI.fromList [Left (1 :: Int), Left 2, Right ("x" :: String), Right "y"]) ] ) (dfIntA <> dfTextA) ) tests :: [Test] tests = [ TestLabel "mergeVerticalWAI" mergeVerticalWAI , TestLabel "mergeVerticalDisjointSchemas" mergeVerticalDisjointSchemas , TestLabel "mergeVerticalWithEmptyLeft" mergeVerticalWithEmptyLeft , TestLabel "mergeVerticalWithEmptyRight" mergeVerticalWithEmptyRight , TestLabel "mergeHorizontalWAI" mergeHorizontalWAI , TestLabel "mergeHorizontalWithEmptyRight" mergeHorizontalWithEmptyRight , TestLabel "mergeHorizontalWithEmptyLeft" mergeHorizontalWithEmptyLeft , TestLabel "mergeVerticalDifferentTypesSameColumnName" mergeVerticalDifferentTypesSameColumnName ]