我在R中构建一个函数(或使用一些巧妙应用)时遇到了一些麻烦。我有一个这样的数据集:
df<- data.frame( id <-sample(1:10,100, replace = T),
price <-runif(20)*100,
q = sample(1:100,100, replace = T))
colnames(df)<-c("id","price","quantity")
现在我需要计算每个ID的平均价格。所以我可以通过每个不同的ID来做到这一点:
sum(((df$p[df$id == "1" ])*(df$q[df$id == "1" ])/(sum(df$q[df$id == "1" ]))))
但是如何让它遍历df $ id的所有可能值并将其打印为矩阵/ df,其中还包含ID和总和?我有大约6000个不同的ID和大约180000个障碍物。如果它也可以快速完成它会很好吗?
以不同的方式将其分解,假设这是我的数据:
id price quantity
1 10 2
1 20 1
1 50 5
2 5 5
2 3 6
2 10 4
所以这里ID = 1的解决方案是:( 10 * 2 + 20*1 +50 * 5 ) / (2+1+5) = 36.25
这给了我价格pr。所有单位的单位为ID = 1.
使用set.seed(1234)
和此数据表进行了更新:
set.seed(1234)
df<- data.frame( id <-sample(1:10,100, replace = T),
price <-runif(20)*100,
q = sample(1:100,100, replace = T))
colnames(df)<-c("id","price","quantity")
结果应如下所示:
id avg.price.per.unit
1 33,71
2 29,84
3 44,53
4 36,27
5 69,63
6 35,99
7 45,26
8 58,32
9 33,36
10 9,67
四舍五入可能有点偏。
答案 0 :(得分:2)
尝试使用ddply
库中的plyr
。 [编辑]现在海报已经(最终)为我们定义了他/她想要的精确计算,解决方案很简单。
set.seed(1234)
df<- data.frame( id <-sample(1:10,100, replace = T),
price <-runif(20)*100,
q = sample(1:100,100, replace = T))
colnames(df)<-c("id","price","quantity")
library(plyr)
df2 <- ddply(df, .(id), summarise,
price.x.quantity = sum(price*quantity),
sum.q = sum(quantity))
df2$avg <- with(df2, price.x.quantity/sum.q)
df2
这给出了这个:
> df2
id price.x.quantity sum.q avg
1 1 17668.111 524 33.717769
2 2 18559.773 622 29.838863
3 3 35222.731 791 44.529369
4 4 28433.181 784 36.266813
5 5 10304.568 148 69.625462
6 6 31534.830 876 35.998665
7 7 29513.494 652 45.266095
8 8 25542.908 438 58.317141
9 9 22216.174 666 33.357619
10 10 2263.581 234 9.673423
>
答案 1 :(得分:2)
您可以在所有唯一ID中应用此功能:
avgPrices <- sapply(unique(df$id), function(i) {
sum(((df$p[df$id == i ])*(df$q[df$id == i ])/(sum(df$q[df$id == i ]))))
})
result <- cbind(unique(df$id), avgPrices)
colnames(result) <- c("id", "avg.price")
或者更简单地使用plyr
包:
library(plyr)
ddply(df, .(id), summarize, avg.price=sum(price/quantity))
或者您可以采用SQL
方法:
library(sqldf)
sqldf("SELECT id, sum(price/quantity) AS 'avg.price' FROM df GROUP BY id")