【问题标题】:How to add the value of a row to other rows based on some criteria in R?如何根据 R 中的某些条件将一行的值添加到其他行?
【发布时间】:2021-07-16 01:49:27
【问题描述】:

我有一个成本面板数据,每月对各种产品类型进行抽样。我还有不属于任何产品类型的“通用”成本。一个超级简单的代表df是这样的:

type <- c("A","A","B","B","C","C","Generic","Generic")
year <- c(2020,2020,2020,2020,2020,2020,2020,2020)
month <- c(1,2,1,2,1,2,1,2)
cost <- c(1,2,3,4,5,6,600,630)
volume <- c(10,11,20,21,30,31,60,63)
df <- data.frame(type,year,month,cost,volume)
type      year  month  cost  volume
 A        2020  1      1     10
 A        2020  2      2     11
 B        2020  1      3     20
 B        2020  2      4     21
 C        2020  1      5     30 
 C        2020  2      6     31
 Generic  2020  1      600   60
 Generic  2020  2      630   63


我需要根据产品类型的“数量”将“通用”成本分配给它们。

例如,

对于 2020-1,体积比

  • 产品类型 A:10 / (10 + 20 + 30) = 1/6
  • 产品类型 B:20 / (10 + 20 + 30) = 2/6
  • 产品类型 C:30 / (10 + 20 + 30) = 3/6

对于2020-2,体积比

  • 产品类型 A:11 / (11 + 21 + 31) = 11/63
  • 产品类型 B:21 / (11 + 21 + 31) = 21/63
  • 产品类型 C:31 / (11 + 21 + 31) = 31/63

因此,我想将 2020-1 年的“通用”成本分配给如下产品类型:

  • 1/6 * 600 = 100 对于产品类型 A
  • 2/6 * 600 = 200(产品类型 B)
  • 3/6 * 600 = 300(产品类型 C)

与 2020-2 年类似,我想分配“通用”成本,例如:

  • 11/63 * 630 = 110 适用于产品类型 A
  • 21/63 * 630 = 210 适用于产品类型 B
  • 31/63 * 630 = 310 适用于产品类型 C

最后,我想得到以下数据框:

type      year  month  new_cost  volume
 A        2020  1      101       10
 A        2020  2      112       11
 B        2020  1      203       20
 B        2020  2      214       21
 C        2020  1      305       30 
 C        2020  2      316       31

我已经有了原始数据框中“通用”类型的总体积,所以不需要单独计算。

我试图通过dplyr 包的group_by()mutate() 函数进行这些计算,但我不知道如何。

感谢任何帮助。

【问题讨论】:

    标签: r group-by tidyverse dplyr


    【解决方案1】:

    我们可以使用 data.table 来做到这一点,首先分别合并通用成本,然后根据每个月/年中每种类型构成的数量百分比来分配它们:

    df <- setDT(df)
    generic <- df[type == "Generic"]
    setnames(generic, "cost", "generic_cost")
    df <- df[type !="Generic"]
    df[, volume_ratio:=volume/sum(volume), by = c("year", "month")]
    df <- merge(df, generic[,c("year", "month", "generic_cost")], by = c("year", "month"))
    df[,new_cost:=cost + (generic_cost*volume_ratio)]
    

    这给了我们:

    df
       year month type cost volume volume_ratio generic_cost new_cost
    1: 2020     1    A    1     10    0.1666667          600      101
    2: 2020     1    B    3     20    0.3333333          600      203
    3: 2020     1    C    5     30    0.5000000          600      305
    4: 2020     2    A    2     11    0.1746032          630      112
    5: 2020     2    B    4     21    0.3333333          630      214
    6: 2020     2    C    6     31    0.4920635          630      316
    

    这有一些额外的列,但新的成本似乎是最重要的列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      相关资源
      最近更新 更多