我是 R 新手,在按日期聚合时遇到一些困难。我有每个日期包含多个价格和数量条目的时间序列数据。实际数据更复杂,但看起来像这样:
price<-c(1.50,3,1.50,3,3,2.90,3)
quantity<-c(10,5,10,5,5,5,5)
date<-c('01/09/21','01/09/21','01/16/21','01/16/21','01/23/21','01/30/21','01/30/21')
df<-data.frame(date,price,quantity)
日期 | 价格 | 数量 |
---|---|---|
01/09/21 | 1.5 | 10 |
01/09/21 | 3 | 5 |
21/16/01 | 1.5 | 10 |
21/16/01 | 3 | 5 |
21/01/23 | 3 | 5 |
01/30/21 | 2.9 | 5 |
01/30/21 | 3 | 5 |
我想创建一个新的数据框,其中仅包含四个单独的日期和每个日期的单个价格值。为此,我尝试计算每个日期的加权平均价格,类似于下面的示例:
日期 | 价格加权 |
---|---|
01/09/21 | 2 |
21/16/01 | 2 |
21/01/23 | 3 |
01/30/21 | 2.95 |
我尝试过使用
price_weighted<-aggregate(price~date,df,weighted.mean)
,它返回的结果与我想要的类似,但由于某种原因,它计算的是平均价格而不是加权平均值。任何建议将不胜感激!
您可以使用 dplyr 来完成此操作,方法是将价格乘以数量除以当天的总数量。
library(dplyr)
price<-c(1.50,3,1.50,3,3,2.90,3)
quantity<-c(10,5,10,5,5,5,5)
date<-c('01/09/21','01/09/21','01/16/21','01/16/21','01/23/21','01/30/21','01/30/21')
df<-data.frame(date,price,quantity)
df %>%
group_by(date) %>%
summarise(wt_mean = sum(price * quantity/sum(quantity)))
#> # A tibble: 4 × 2
#> date wt_mean
#> <chr> <dbl>
#> 1 01/09/21 2
#> 2 01/16/21 2
#> 3 01/23/21 3
#> 4 01/30/21 2.95
您也可以使用基本 R 中的
by()
或 tapply()
来完成此操作:
by(df, list(df$date), function(x)Hmisc::wtd.mean(x$price, weights=x$quantity))
#> : 01/09/21
#> [1] 2
#> ------------------------------------------------------------
#> : 01/16/21
#> [1] 2
#> ------------------------------------------------------------
#> : 01/23/21
#> [1] 3
#> ------------------------------------------------------------
#> : 01/30/21
#> [1] 2.95
tapply(df, df$date, function(x)Hmisc::wtd.mean(x$price, weights=x$quantity))
#> 01/09/21 01/16/21 01/23/21 01/30/21
#> 2.00 2.00 3.00 2.95
创建于 2024-04-13,使用 reprex v2.0.2
考虑使用
aggregate
使用 transform
运行前后计算:
aggregate(
x = cbind(revenue, quantity) ~ date,
data = transform(df, revenue = price * quantity),
FUN = sum
) |> transform(
weighted_average = revenue / quantity
)
# date revenue quantity weighted_average
# 1 01/09/21 30.0 15 2.00
# 2 01/16/21 30.0 15 2.00
# 3 01/23/21 15.0 5 3.00
# 4 01/30/21 29.5 10 2.95
底座安装中有
weighted.mean()
。
> by(df, df$date, \(x) {
+ with(x, data.frame(date=el(date),
+ price_weighted=weighted.mean(price, quantity/sum(quantity))))
+ }) |> do.call(what='rbind')
date price_weighted
01/09/21 01/09/21 2.00
01/16/21 01/16/21 2.00
01/23/21 01/23/21 3.00
01/30/21 01/30/21 2.95