# npdsim

    library(npdsim)

The package npdsim simulates the demand for products over their life cycle. npdsim also simulates the attributes of these products. The simulated data (demand and attributes) can help forecasters and researchers develop, evaluate and compare new product demand forecasting approaches.

npdsim uses the assumption that each new product has a shape and a level where the shape is the normalized demand over the product life cycle, and the level is the cumulative demand across those periods.

Each product has a shape and a level. The demand of a product during a time period is its shape level, plus some noise.

Each product has attributes. Some attributes are related to the shape of this product, and some are related to its level. We consider two situations: 1) independent attributes and 2) dependent attributes. In the case of independent attributes, the attributes related to the shape are different than the attributes related to the level. In the case of dependent attributes, some attributes are only related to the shape, some are only related to the level and some are related to the shape and the level, at the same time (the shape and the level are dependent). In both cases, some attributes are neither related to shape nor to level.

Products that have the same shape (level), have the same values for their attributes related to shape (level) with some noise.

With the function npd_data_sim(), you can generate a data set that contains the demand and attributes of products. For example :

    npd_data1 <- npd_data_sim(products_number=100,
                             periods_number=30,
                             shape_number=5,
                             level_number=20)

    str(npd_data1)
    #> 'data.frame':    3000 obs. of  13 variables:
    #>  $ product_id : int  1 1 1 1 1 1 1 1 1 1 ...
    #>  $ time       : num  1 2 3 4 5 6 7 8 9 10 ...
    #>  $ demand     : num  82 118 137 160 177 177 202 186 223 245 ...
    #>  $ attribute1 : num  0.252 0.252 0.252 0.252 0.252 ...
    #>  $ attribute9 : num  0.876 0.876 0.876 0.876 0.876 ...
    #>  $ attribute2 : num  0.152 0.152 0.152 0.152 0.152 ...
    #>  $ attribute10: num  0.614 0.614 0.614 0.614 0.614 ...
    #>  $ attribute5 : num  0.287 0.287 0.287 0.287 0.287 ...
    #>  $ attribute7 : num  0.962 0.962 0.962 0.962 0.962 ...
    #>  $ attribute6 : num  0.0527 0.0527 0.0527 0.0527 0.0527 ...
    #>  $ attribute8 : num  0.631 0.631 0.631 0.631 0.631 ...
    #>  $ attribute3 : num  0.225 0.225 0.225 0.225 0.225 ...
    #>  $ attribute4 : num  0.801 0.801 0.801 0.801 0.801 ...

We plot below the demand of the first 5 products:

We can specify the type of demand shape and the number of attributes (and other information). For example :

    npd_data2 <- npd_data_sim(products_number=10,
                   periods_number=40,
                   shape_number=5,
                   shape_type="bass",
                   level_number=20,
                   level_range=1000:10000,
                   noise_cv=0.05,
                   attribute_type="ind",
                   attributes_number=15,
                   shape_attributes_number=7,
                   level_attributes_number=5)

    str(npd_data2)
    #> 'data.frame':    400 obs. of  18 variables:
    #>  $ product_id : int  1 1 1 1 1 1 1 1 1 1 ...
    #>  $ time       : num  1 2 3 4 5 6 7 8 9 10 ...
    #>  $ demand     : num  16 29 33 36 39 39 41 48 46 51 ...
    #>  $ attribute13: num  0.958 0.958 0.958 0.958 0.958 ...
    #>  $ attribute2 : num  0.418 0.418 0.418 0.418 0.418 ...
    #>  $ attribute9 : num  0.418 0.418 0.418 0.418 0.418 ...
    #>  $ attribute7 : num  0.12 0.12 0.12 0.12 0.12 ...
    #>  $ attribute4 : num  0.16 0.16 0.16 0.16 0.16 ...
    #>  $ attribute8 : num  0.35 0.35 0.35 0.35 0.35 ...
    #>  $ attribute6 : num  0.539 0.539 0.539 0.539 0.539 ...
    #>  $ attribute14: num  0.3 0.3 0.3 0.3 0.3 ...
    #>  $ attribute10: num  0.737 0.737 0.737 0.737 0.737 ...
    #>  $ attribute1 : num  0.324 0.324 0.324 0.324 0.324 ...
    #>  $ attribute12: num  0.592 0.592 0.592 0.592 0.592 ...
    #>  $ attribute11: num  0.119 0.119 0.119 0.119 0.119 ...
    #>  $ attribute3 : num  0.72 0.72 0.72 0.72 0.72 ...
    #>  $ attribute5 : num  0.904 0.904 0.904 0.904 0.904 ...
    #>  $ attribute15: num  0.765 0.765 0.765 0.765 0.765 ...

The generated demand for the first 5 products (product_id=1,2,…,5) is:

npdsim also contains functions that only generate demand, shape, or attributes.

## Simulating demand

The function `demand_sim` creates the demand for new products by simulating first the level and then the shape. For example,

    demand1 <- demand_sim(products_number=100,
                          periods_number=20,
                          shape_number=5,
                          shape_type="bass",
                          level_number=20,
                          level_range=1000:10000,
                          noise_cv=0.05)

In this example, we create the demand for 100 new products over a life cycle of 20 periods where the number of shapes is 5 and the number of levels is 20. The range [1000,10000] is the range from which the level for each product is sampled. The parameter `noise_cv` is the coefficient of variation of the normally distributed noise applied to the generated pure demand (the pure demand is the product of the shape and level). In the example above, we take assume that the type of shapes of the 100 new products is a Bass curve where each new product has a different shape (in this case, different values for the parameters of the Bass curve are taken for each product).

## Simulating level

Regarding the level, for each product, we sample the level from level_range, parameter of the function `demand_sim`, the default range is [1000, 10000]. The sampling is done using the function `sample`.

## Simulating shape

npdsim first generates generic shapes, and then assign randomoly a shape to each product. The function `shape_sim` creates the generic shapes. For example:

    shape1 <- shape_sim(periods_number=20,
                        shape_number=5,
                        shape_type="trapezoid")

    head(shape1)
    #>   time       shape assigned_shape
    #> 1    0 0.000000000              1
    #> 2    1 0.006074564              1
    #> 3    2 0.012149128              1
    #> 4    3 0.018223691              1
    #> 5    4 0.024298255              1
    #> 6    5 0.030372819              1

The previous example creates five different shapes over a time interval of 20 periods (from period 1 to period 20), where the five different shape have the same type of shape (trapezoidal). The generated shapes are:

The parameter `shape_type` in the function `shape_sim` can take the following values: “triangle”, “trapezoid”, “bass”, “random” and “intro & growth”. The type “random” picks one of the types “triangle”, “trapezoid”, “bass” randomly for each product. The type “intro & growth” is used for the shapes of the introduction and growth phases.

For example:

    shape2 <- shape_sim(periods_number=20,
                        shape_number=5,
                        shape_type="random") #random is the default value

    shape3 <- shape_sim(periods_number=20,
                        shape_number=5,
                        shape_type="intro & growth")

If you want to create directly one of the types “triangle”, “trapezoid”, “bass”, “random” or “intro & growth” for all the products, you can use one of the following functions `shape_sim_triangle`, `shape_sim_trapezoid`, `shape_sim_bass`, `shape_sim_random` or `shape_sim_ig`, respectively.

The shapes “triangle”, “trapezoid”, “bass”, “random” correspond to the shapes of product with a relatively short maturity period such as personal computers and durable products in general (we assume that products have four phases in their life cycle: introduction, growth, maturity and decline).

For products with a long maturity period, we can simulate only the demand over the introduction and growth phases (by setting shape_type=“intro & growth”).