Signature Description

enum class shift_policy : unsigned char  {
    down = 1,  // Shift/rotate the content of all columns down
    up = 2,    // Shift/rotate the content of all columns up
    left = 3,  // Shift/rotate the columns to the left
    right = 4, // Shift/rotate the columns to the right
}; 
This policy is relative to a tabular data structure. The index column always remains unchanged

Signature Description Parameters

template<typename ... Ts>
void
self_shift(std::size_t periods, shift_policy sp);
        
It shifts all the columns in self up, down, left or right based on shift_policy.
When shifting up or down, values that are shifted out will be assigned to NaN.
When shifting left or right, columns that are shifted out will be removed from the DataFrame.
The index column remains unchanged.
If user shifts with periods that is larger than the column length, all values in that column become NaN.
Ts: The list of types for all columns. A type should be specified only once.
periods: Number of periods to shift
shift_policy: Specifies the direction (i.e. up/down) to shift

template<typename ... Ts>
StdDataFrame<I>
shift(std::size_t periods, shift_policy sp) const; 
        
It is exactly the same as self_shift, but it leaves self unchanged and returns a new DataFrame with columns shifted. Ts: The list of types for all columns. A type should be specified only once.
periods: Number of periods to shift
shift_policy: Specifies the direction (i.e. up/down) to shift

template<typename T>
std::vector
shift(const char *col_name,
      std::size_t periods,
      shift_policy sp) const;
        
This copies the named column into another vector and shifts it up or down and returns it.
It is handy to create columns of shifted data in the dataframe for machine-learning analysis (see code sample below)
T: Type of the col_name colum
col_name: Name of the column
periods: Number of periods to shift
shift_policy: Specifies the direction (in this case up/down) to shift
static void test_shifting_up_down()  {

    std::cout << "\nTesting Shifting Up/Down ..." << std::endl;

    std::vector<unsigned long>  idx =
        { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466 };
    std::vector<double>         d1 = { 15, 16, 15, 18, 19, 16, 21, 0.34, 1.56, 0.34, 2.3, 0.34, 19.0 };
    std::vector<int>            i1 = { 22, 23, 24, 25, 99 };
    std::vector<std::string>    s1 =
        { "qqqq", "wwww", "eeee", "rrrr", "tttt", "yyyy", "uuuu", "iiii", "oooo", "pppp", "2222", "aaaa", "dddd", "ffff" };
    MyDataFrame                 df;

    df.load_data(std::move(idx),
                 std::make_pair("dbl_col", d1),
                 std::make_pair("int_col", i1),
                 std::make_pair("str_col", s1));

    std::cout << "Original DF:" << std::endl;
    df.write<std::ostream, double, int, std::string>(std::cout);

    auto    sudf = df.shift<double, int, std::string>(3, shift_policy::up);

    std::cout << "Shifted Up DF:" << std::endl;
    sudf.write<std::ostream, double, int, std::string>(std::cout);

    auto    sddf = df.shift<double, int, std::string>(3, shift_policy::down);

    std::cout << "Shifted Down DF:" << std::endl;
    sddf.write<std::ostream, double, int, std::string>(std::cout);
}

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

static void test_shifting_column()  {

    std::cout << "\nTesting shifting columns ..." << std::endl;

    std::vector<unsigned long>  idx =
        { 123450, 123451, 123452, 123453, 123454, 123455, 123456, 123457, 123458, 123459, 123460, 123461, 123462, 123466 };
    std::vector<double>         d1 = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 };
    MyDataFrame                 df;

    df.load_data(std::move(idx), std::make_pair("dbl_col", d1));

    df.load_column("dbl_col t-1", df.shift<double>("dbl_col", 1, shift_policy::down));
    df.load_column("dbl_col t-2", df.shift<double>("dbl_col", 2, shift_policy::down));
    df.load_column("dbl_col t-3", df.shift<double>("dbl_col", 3, shift_policy::down));
    df.load_column("dbl_col t-4", df.shift<double>("dbl_col", 4, shift_policy::down));
    df.load_column("dbl_col t-5", df.shift<double>("dbl_col", 5, shift_policy::down));
    df.load_column("dbl_col t-6", df.shift<double>("dbl_col", 6, shift_policy::down));
    df.load_column("dbl_col t-7", df.shift<double>("dbl_col", 7, shift_policy::down));

    df.load_column("dbl_col t+1", df.shift<double>("dbl_col", 1, shift_policy::up));
    df.load_column("dbl_col t+2", df.shift<double>("dbl_col", 2, shift_policy::up));
    df.load_column("dbl_col t+3", df.shift<double>("dbl_col", 3, shift_policy::up));
    df.load_column("dbl_col t+4", df.shift<double>("dbl_col", 4, shift_policy::up));
    df.load_column("dbl_col t+5", df.shift<double>("dbl_col", 5, shift_policy::up));
    df.load_column("dbl_col t+6", df.shift<double>("dbl_col", 6, shift_policy::up));
    df.load_column("dbl_col t+7", df.shift<double>("dbl_col", 7, shift_policy::up));

    df.write<std::ostream, double>(std::cout, io_format::csv2);
}
C++ DataFrame