从一个数据框计算加权平均值并将列添加到另一个数据框

时间:2017-01-24 21:01:00

标签: r

我想从一个数据框创建加权平均值并将其添加到另一个数据框。通常,我在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添加到Customer数据框中,该数据框是该客户的加权平均TotalCost,计算的Sum(Weight * TotalCost)/ Sum(Weight)受CustomerID字段限制,其中Year&gt; 2015年。

我已经看过通过Customer表循环,但我很确定有更好的矢量化解决方案。

另外(后期编辑),如果年份来自Customer表而不是明确定义,我想知道如何实现这一点。以下是新的客户数据框:

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 个答案:

答案 0 :(得分: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

如果这仍然是错误的输出,并且您仍然感兴趣,请发布正确输出的示例。

答案 1 :(得分:1)

考虑使用extension String { func hasLettersInCommon(with other: String) -> Bool { let selfLetters = Set(self.characters) let otherLetters = other.characters let commonLetters = selfLetters.intersection(otherLetters) return !commonLetters.isEmpty } } var pets = ["cat" : "dog", "rat" : "snake"] for (key, value) in pets { print(key, value, key.hasLettersInCommon(with: value)) } aggregate()transform()的基础R解决方案:

merge()