pipts
pipts

Reputation: 87

create a for loop and add row to the df after each iteration

I want to construct an empty df with the specific columns and create a loop that adds a row in every iteration

type <- c("AAA","BBB","CCC")
price <-c(0.5, 0.7, 0.2)
fixed_cost1<- 500
fixed_cost <- 200
Quantity<-c(400,700)
Month <-c(1,2,3)

df<-as.data.frame(matrix(,ncol=6,nrow=0))

I want to create a for loop that produces the data frame below. I want to calculate the total cost for every "type" for a 3-month period and for different "quantities" .The calculation of Total cost is the (price[i]*Quantity[i]+fixed_cost1+ fixed_cost2)* Month[i] . The final df will be very big as the total cost calculation has to be done for every type, for all the months for the quantity 400 and then the same for all the months for the quantity 700. Thank you for your time

type price fixed_cost1 fixed_cost2 Month Quantity Total_Cost
AAA 0.5 500 200 1 400 900
AAA 0.5 500 200 2 400 1800
AAA 0.5 500 200 3 400 2700
AAA 0.5 500 200 1 700 1050
AAA 0.5 500 200 2 700 2100
AAA 0.5 500 200 3 700 3150
BBB 0.7 500 200 1 400 980
---- --- --- --- -- --- ----
BBB 0.7 500 200 3 700 1190

Upvotes: 0

Views: 104

Answers (1)

r2evans
r2evans

Reputation: 160447

As I mentioned in the comments, it is really a bad idea to try to add rows iteratively to a frame, succumbing to the second circle of The R Inferno (Growing Objects). But I think we can build this all at once instead using expand.grid.

Notes:

  • Your expected output cycles the right-most columns first, whereas expand.grid cycles the left-most columns first. The difference is completely aesthetic. In order to more closely (but not exactly) match your expected output, I will change (mostly reverse) the order of arguments, then re-order the columns post-expand.grid (with [,6:1]). If this bothers you, order the columns the way you want, it changes nothing in the subsequent calculations.

  • I'm not sure if you are intending to have all permutations of each type with each price (nine permutations), or if those two variables are paired (so BBB will only be 0.7). If you mean the former, then we'll start with

    eg <- expand.grid(Month = Month, Quantity = Quantity,
                      fixed_cost2 = fixed_cost, fixed_cost1 = fixed_cost1,
                      price = price, type = type)[,6:1]
    head(eg); tail(eg, 2)
    #   type price fixed_cost1 fixed_cost2 Quantity Month
    # 1  AAA   0.5         500         200      400     1
    # 2  AAA   0.5         500         200      400     2
    # 3  AAA   0.5         500         200      400     3
    # 4  AAA   0.5         500         200      700     1
    # 5  AAA   0.5         500         200      700     2
    # 6  AAA   0.5         500         200      700     3
    #    type price fixed_cost1 fixed_cost2 Quantity Month
    # 53  CCC   0.2         500         200      700     2
    # 54  CCC   0.2         500         200      700     3
    nrow(eg)
    # [1] 54
    

    However, if BBB is always 0.7, then we need to change that slightly:

    eg <- expand.grid(Month = Month, Quantity = Quantity,
                      fixed_cost2 = fixed_cost, fixed_cost1 = fixed_cost1,
                      tprow = seq_len(nrow(typeprice)))[,5:1]
    eg <- cbind(typeprice[eg$tprow,], eg[,-1])
    head(eg,3); tail(eg,2)
    #     type price fixed_cost1 fixed_cost2 Quantity Month
    # 1    AAA   0.5         500         200      400     1
    # 1.1  AAA   0.5         500         200      400     2
    # 1.2  AAA   0.5         500         200      400     3
    #     type price fixed_cost1 fixed_cost2 Quantity Month
    # 3.4  CCC   0.2         500         200      700     2
    # 3.5  CCC   0.2         500         200      700     3
    nrow(eg)
    # [1] 18
    

Use whichever of the egs makes sense to you. I'll infer the second for now.

From here, it seems like a simple transform (or dplyr::mutate if you prefer):

transform(eg, Total_Cost = (price * Quantity + fixed_cost1 + fixed_cost2) * Month)
#     type price fixed_cost1 fixed_cost2 Quantity Month Total_Cost
# 1    AAA   0.5         500         200      400     1        900
# 1.1  AAA   0.5         500         200      400     2       1800
# 1.2  AAA   0.5         500         200      400     3       2700
# 1.3  AAA   0.5         500         200      700     1       1050
# 1.4  AAA   0.5         500         200      700     2       2100
# 1.5  AAA   0.5         500         200      700     3       3150
# 2    BBB   0.7         500         200      400     1        980
# 2.1  BBB   0.7         500         200      400     2       1960
# 2.2  BBB   0.7         500         200      400     3       2940
# 2.3  BBB   0.7         500         200      700     1       1190
# 2.4  BBB   0.7         500         200      700     2       2380
# 2.5  BBB   0.7         500         200      700     3       3570
# 3    CCC   0.2         500         200      400     1        780
# 3.1  CCC   0.2         500         200      400     2       1560
# 3.2  CCC   0.2         500         200      400     3       2340
# 3.3  CCC   0.2         500         200      700     1        840
# 3.4  CCC   0.2         500         200      700     2       1680
# 3.5  CCC   0.2         500         200      700     3       2520

Upvotes: 1

Related Questions