2017-01-24 126 views
0

我想從一個數據框創建加權平均值並將其添加到另一個數據框。通常,我在SQL中這樣做,但我不能在這種情況下。我在這裏給出的例子非常簡單。從一個數據框計算加權平均數並將列添加到另一個數據框

第一個數據框叫做Customer。它有一個CustomerID列。

Customer <- data.frame(
    CustomerID = sample(1:10) 
) 

第二個數據幀被稱爲Order。它有四個字段:CustomerID,Year,Weight和TotalCost。

Order <- data.frame(
    CustomerID = sample(1:9, 100, replace=TRUE), 
    Year = sample(2014:2016, 100, replace=TRUE), 
    Weight = sample(1:3, 100, replace=TRUE), 
    TotalCost = sample(200:400, 100, replace=TRUE) 
) 

我想列WeightedCost添加到客戶數據幀是該客戶,計算出的和(重量* TOTALCOST)/薩姆(重量)由客戶ID字段,並且其中限定的加權平均TOTALCOST年> 2015年。

我看了看循環客戶表,但我很確定有一個更好的矢量化解決方案。

此外(後期編輯),我想知道如何實現這一點,如果一年來自客戶表而不是明確定義。這是新的客戶數據幀:

c = c(1,1,2,2,3,3,4,4,5,5) 
y = c(2014,2015,2014,2015,2014,2015,2014,2015,2014,2015) 
Customer <- data.frame(
    CustomerID = c, 
    Year = y 
) 

回答

2

更新

不知道,如果OP仍感興趣,但爲後人...

首先,我可以說,如果你問首先是正確的問題,並且顯示了你想要的結果,你很可能會得到更快的答案。其次,我已經回到我的第一個答案,因爲它至少回答了原來措辭的問題,而後來的編輯顯然不是你想要的。

已回滾答案

library(dplyr) 
Order %>% 
    filter(Year > 2015) %>% 
    group_by(CustomerID) %>% 
    transmute(w.mean = sum(TotalCost * Weight)/sum(Weight) %>% 
    slice(1) %>% 
    full_join(Customer) 

編輯 - 添加加盟客戶數據

結果

CustomerID  w.mean 
    1   321.5556 
    2   264.3333 
    3   231.2000 
    4   397.0000 
    5   250.0000 
    6   266.6250 
    7   237.0000 
    8   258.2000 
    9   384.8333 
    10   NA 

更新答案

最後我添加了一系列新操作,將所有加權成本從指定年份添加。我仍然在猜測你的結果應該是什麼樣子,但這就是你要求的,對吧?

數據操作

Order %>% 
    group_by(CustomerID, Year) %>% 
    summarize(w.mean = weighted.mean(TotalCost, Weight)) %>% #sum(TotalCost * Weight)/sum(Weight)) %>% 
    arrange(CustomerID, desc(Year)) %>% 
    mutate(w.mean = cumsum(w.mean)) %>% 
    right_join(Customer2, c('CustomerID', 'Year')) 

輸出

CustomerID Year w.mean 
     1 2014 939.3500 
     1 2015 602.3500 
     2 2014 860.7063 
     2 2015 566.9286 
     3 2014 780.8819 
     3 2015 522.4274 
     4 2014 922.6154 
     4 2015 569.6154 
     5 2014 945.9679 
     5 2015 654.7179 

如果這仍然是錯誤的輸出,而你仍然感興趣,請正確的輸出的一個例子。

+0

我不熟悉的dplyr包,雖然我沒有安裝它,並添加庫。當我將你的代碼寫入R時,它不會「完成」。它正在尋找另一行代碼。 –

+0

是的,在'transmute'行末尾缺少一個括號 - 我昨晚編輯了它,我猜是在你複製之後? - 我只是雙重檢查它 - 現在看起來很好,對不起:) – user127649

+0

如果年(在這種情況下:2015年)是客戶表中的一列,我將如何實施? –

1

考慮與aggregate()transform(),並merge()一個基礎R解決方案:

# CREATE WEIGHT COST PRODUCT UNIT LEVEL COLUMN 
Order$WgtCostProd <- Order$Weight * Order$TotalCost 

# AGGREGATE WITH NEW WEIGHTEDCOST COLUMN 
OrderAgg <- transform(aggregate(.~CustomerID, Order[Order$Year > 2015,], FUN=sum), 
         WeightedCost = WgtCostProd/Weight) 

# LEFT JOIN MERGE TO ORIGINAL DATAFRAME 
Customer <- merge(Customer, OrderAgg[c("CustomerID", "WeightedCost")], 
        by="CustomerID", all.x=TRUE) 
Customer 

# CustomerID WeightedCost 
# 1   1  302.6667 
# 2   2  281.2941 
# 3   3  229.6667 
# 4   4  308.6000 
# 5   5  305.6667 
# 6   6  315.0000 
# 7   7  312.5833 
# 8   8  333.0000 
# 9   9  295.6667 
# 10   10   NA 
+0

這給了我在Customer表中的WeightedCost.x(CustomerId或NAN)和WeightedCost.y(WeightedCost)列。 –

+1

您正在不斷合併到* Customer * df。每次運行時,用'data.frame'調用重新運行初始* Customer *。或者最後,創建一個新的數據框,而不是像這個答案顯示的那樣覆蓋它。 – Parfait

+0

如果年份(本例中爲2015)是客戶表中的一列,我將如何執行此操作? –

相關問題