通过索引聚合并在 R 中重新加权

Aggregating by indeces and reweighting in R

我有大量按州、日期和 UPC(产品代码)索引的价格数据。我想汇总 UPC,并通过加权平均合并价格。我会尝试解释它,但您可能只想阅读下面的代码。

数据集中的每个观察值是:UPC、日期、州、价格和重量。我想以这种方式汇总 UPC 索引:

获取具有相同日期和状态的所有数据点,并将它们的价格乘以它们的权重并求和。这显然创建了一个加权平均值,我称之为 priceIndex。但是,对于某些日期和状态组合,权重加起来不等于 1。因此,我想创建两个额外的列:一个用于每个日期和状态组合的权重总和。第二个是重新加权平均值:即,如果原来的两个权重是 .5 和 .3,则将它们更改为 .5/(.5+.3)=.625 和 .3/(.5+.3)= .375,然后将加权平均值重新计算为另一个价格指数。

这就是我的意思:

upc=c(1153801013,1153801013,1153801013,1153801013,1153801013,1153801013,2105900750,2105900750,2105900750,2105900750,2105900750,2173300001,2173300001,2173300001,2173300001)
date=c(200601,200602,200603,200603,200601,200602,200601,200602,200603,200601,200602,200601,200602,200603,200601)
price=c(26,28,27,27,23,24,85,84,79.5,81,78,24,19,98,47)
state=c(1,1,1,2,2,2,1,1,2,2,2,1,1,1,2)
weight=c(.3,.2,.6,.4,.4,.5,.5,.5,.45,.15,.5,.2,.15,.3,.45)

# This is what I have:
data <- data.frame(upc,date,state,price,weight)
data

# These are a few of the weighted calculations:
# .3*26+85*.5+24*.2 = 55.1
# 28*.2+84*.5+19*.15 = 50.45
# 27*.6+98*.3 = 45.6
# Etc. etc.

# Here is the reweighted calculation for date=200602 & state==1:
# 28*(.2/.85)+84*(.5/.85)+19*(.15/.85) = 50.45
# Or, equivalently:
# (28*.2+84*.5+19*.15)/.85 = 50.45

# This is what I want:
date=c(200601,200602,200603,200601,200602,200603)
state=c(1,1,1,2,2,2)
priceIndex=c(55.1,50.45,45.6,42.5,51,46.575)
totalWeight=c(1,.85,.9,1,1,.85)
reweightedIndex=c(55.1,59.35294,50.66667,42.5,51,54.79412)
index <- data.frame(date,state,priceIndex,totalWeight,reweightedIndex)
index

此外,这并不重要,但数据集中大约有 35 个州、150 个 UPC 和 84 个日期——因此有很多观察结果。

非常感谢。

我们可以使用group by summarize操作之一。使用 data.table,我们将 'data.frame' 转换为 'data.table'(setDT(data),按 'date'、'state' 分组,我们得到 sum 'price'和'weight'的乘积和sum(weight)作为临时变量,然后在list的基础上创建3个变量。

library(data.table) 
setDT(data)[, {tmp1 = sum(price*weight)
                tmp2 = sum(weight)
        list(priceIndex=tmp1, totalWeight=tmp2,
              reweigthedIndex = tmp1/tmp2)}, .(date, state)]
#    date state priceIndex totalWeight reweightedIndex
#1: 200601     1     55.100        1.00        55.10000
#2: 200602     1     50.450        0.85        59.35294
#3: 200603     1     45.600        0.90        50.66667
#4: 200603     2     46.575        0.85        54.79412
#5: 200601     2     42.500        1.00        42.50000
#6: 200602     2     51.000        1.00        51.00000

或者使用 dplyr,我们可以使用 summarise 在按 'date' 和 'state' 分组后创建 3 列。

library(dplyr)
data %>% 
  group_by(date, state) %>% 
  summarise(priceIndex = sum(price*weight),
            totalWeight = sum(weight),
            reweightedIndex = priceIndex/totalWeight)
#   date state priceIndex totalWeight reweightedIndex
#   (dbl) (dbl)      (dbl)       (dbl)           (dbl)
#1 200601     1     55.100        1.00        55.10000
#2 200601     2     42.500        1.00        42.50000
#3 200602     1     50.450        0.85        59.35294
#4 200602     2     51.000        1.00        51.00000
#5 200603     1     45.600        0.90        50.66667
#6 200603     2     46.575        0.85        54.79412