【问题标题】:create a for loop and add row to the df after each iteration创建一个 for 循环并在每次迭代后向 df 添加行
【发布时间】:2021-07-21 12:43:16
【问题描述】:

我想用特定的列构造一个空的 df 并创建一个循环,在每次迭代中添加一行

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))

我想创建一个生成下面数据框的 for 循环。我想计算 3 个月内每种“类型”和不同“数量”的总成本。总成本的计算是 (price[i]*Quantity[i]+fixed_cost1+ fixed_cost2)* Month[i] 。最终的df 将非常大,因为必须对每种类型进行总成本计算,数量为 400 的所有月份,数量 700 的所有月份都相同。谢谢您的时间

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

【问题讨论】:

  • 在我查看您的预期输出之前,请意识到迭代地向帧添加行的缩放比例很差;如果您有兴趣,请阅读The R Inferno 中的“Circle 2:Growing Objects”。长话短说,添加的每一行都会复制整个帧,因此添加的行越多,它在内存中的空间(以及复制它的时间)是通常应该是帧的两倍。有选项,取决于用途...

标签: r for-loop


【解决方案1】:

正如我在 cmets 中提到的,尝试将行迭代地添加到框架中确实是一个坏主意,屈服于 The R Inferno 的第二个圆圈(Growing Objects)。但我认为我们可以一次全部构建,而不是使用expand.grid

注意事项:

  • 您的预期输出首先循环最右边的列,而expand.grid 首先循环最左边的列。 差异完全是美学上的。为了更接近(但不完全)匹配您的预期输出,我将更改(主要是颠倒)参数的顺序,然后重新排列列 post-@987654324 @(与[,6:1])。如果这让您感到困扰,请按照您想要的方式对列进行排序,在后续计算中不会改变任何内容

  • 我不确定您是否打算将每个 type 与每个 price(九个排列)的所有排列组合在一起,或者这两个变量是否成对出现(所以 BBB 只会是 0.7) .如果你指的是前者,那么我们将从

    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
    

    但是,如果BBB 始终是0.7,那么我们需要稍微改变一下:

    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
    

使用对您有意义的egs 中的任何一个。我现在将推断第二个。

从这里开始,这似乎是一个简单的transform(或dplyr::mutate,如果你愿意的话):

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

【讨论】:

  • 我使用了第一个选项并且工作但对于每种类型,它也以排列形式返回价格。正如您所说的那样,每种类型的“AAA”、“BBB”、“CCC”都有自己的价格。这正是您所做的最终输出。我不能理解很多tprow = seq_len(nrow(typeprice)))[,5:1]@r2evans
猜你喜欢
  • 1970-01-01
  • 2019-08-13
  • 2015-03-19
  • 2018-12-27
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-05-23
相关资源
最近更新 更多