2016-02-13 1 views
1

J'ai une tonne de données de prix indexées par État, Date et Code UPC (Product Code). Je veux regrouper UPC, et combiner les prix en prenant une moyenne pondérée. Je vais essayer de l'expliquer, mais vous voudrez peut-être juste lire le code ci-dessous. Chaque observation de l'ensemble de données est: CUP, date, état, prix et poids. Je voudrais agréger l'index UPC de cette façon:Agrégation par indeces et repondération en R

Prendre tous les points de données avec la même date et le même état, et multiplier leurs prix par leurs poids et les résumer. Cela crée évidemment une moyenne pondérée, que j'appelle le priceIndex. Cependant, pour une certaine date, les poids ne totalisent pas 1. Par conséquent, je veux créer deux colonnes supplémentaires: Une pour le total des poids pour chaque date & combo d'état. La seconde est pour une moyenne repondérée: Par exemple, si les deux poids initiaux étaient .5 et .3, changez-les en .5/(.5 + .3) = .625 et .3/(.5 + .3) = .375, puis recalculer la moyenne pondérée en un autre indice de prix.

C'est ce que je veux dire:

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 

En outre, pas qu'il devrait la matière, mais il y a environ 35 états, 150 et 84 UPCs dates dans l'ensemble de données - donc il y a beaucoup d'observations .

Merci beaucoup d'avance.

Répondre

2

Nous pouvons utiliser l'un des groupes par opération récapitulative. Avec data.table, nous convertissons le 'data.frame' en 'data.table' (setDT(data), regroupés par 'date', 'état', nous obtenons le sum du produit de 'prix' et 'poids', et sum(weight) comme variables temporaires , puis créer les 3 variables du list sur cette base.

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 

ou en utilisant dplyr, nous pouvons utiliser summarise pour créer les 3 colonnes après avoir fait le regroupement par « date » et « Etat ».

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 
+0

Pour le dplyr un, quand je sais que je viens d'obtenir une ligne? – ejn

+1

@ejn Pouvez-vous utiliser 'dplyr :: summarise' (dans le cas où vous avez également chargé' plyr' – akrun