Signature Description Parameters

template<typename DF, typename ... Ts>
inline DF df_plus(const DF &lhs, const DF &rhs);
        
This is the global plus (+) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame

template<typename DF, typename ... Ts>
inline DF df_minus(const DF &lhs, const DF &rhs);
        
This is the global minus (-) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame

template<typename DF, typename ... Ts>
inline DF df_multiplies(const DF &lhs, const DF &rhs);
        
This is the global multiplication (*) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame

template<typename DF, typename ... Ts>
inline DF df_divides(const DF &lhs, const DF &rhs);
        
This is the global division (/) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
static void test_dataframe_friend_plus_operator()  {

    std::cout << "\nTesting DataFrame friend plus operator ..." << std::endl;

    MyDataFrame df1;
    MyDataFrame df2;

    try  {
        df1.read("sample_data.csv");
        df2.read("sample_data.csv");
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }

    MyDataFrame result = df_plus<MyDataFrame, unsigned long, int, double, std::string, bool>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
}

// -----------------------------------------------------------------------------

static void test_dataframe_friend_minus_operator()  {

    std::cout << "\nTesting DataFrame friend minus operator ..." << std::endl;

    MyDataFrame df1;
    MyDataFrame df2;

    try  {
        df1.read("sample_data.csv");
        df2.read("sample_data.csv");
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }

    // Notice I am omitting std::string here, since minus is not defined for
    // std::string, and hence it won't compile
    MyDataFrame result = df_minus<MyDataFrame, unsigned long, int, double, bool>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, unsigned long, double, bool>(std::cout);
}

// -----------------------------------------------------------------------------

static void test_dataframe_friend_multiplies_operator()  {

    std::cout << "\nTesting DataFrame friend multiplies operator ..."
              << std::endl;

    std::vector<unsigned long>  idx1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 25, 40, 55 };
    std::vector<unsigned long>  idx2 = { 1, 2, 3, 4, 5, 8, 9, 22, 25, 40 };
    std::vector<double>         d1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<double>         d2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    std::vector<double>         s1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<int>            s2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    MyDataFrame df1;
    MyDataFrame df2;

    df1.load_data(std::move(idx1), std::make_pair("dbl_col", d1), std::make_pair("same_name", s1));
    df2.load_data(std::move(idx2), std::make_pair("dbl_col", d2), std::make_pair("same_name", s2));

    MyDataFrame result = df_multiplies<MyDataFrame, int, double>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, double>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, double>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, double>(std::cout);
}

// -----------------------------------------------------------------------------

static void test_dataframe_friend_divides_operator()  {

    std::cout << "\nTesting DataFrame friend divides operator ..." << std::endl;

    std::vector<unsigned long>  idx1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 25, 40, 55 };
    std::vector<unsigned long>  idx2 = { 1, 2, 3, 4, 5, 8, 9, 22, 25, 40 };
    std::vector<double>         d1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<double>         d2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    std::vector<double>         s1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<int>            s2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    MyDataFrame df1;
    MyDataFrame df2;

    df1.load_data(std::move(idx1), std::make_pair("dbl_col", d1), std::make_pair("same_name", s1));
    df2.load_data(std::move(idx2), std::make_pair("dbl_col", d2), std::make_pair("same_name", s2));

    MyDataFrame result = df_divides<MyDataFrame, int, double>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, double>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, double>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, double>(std::cout);
}
C++ DataFrame