R:data.table 中的透视和小计?
Posted
技术标签:
【中文标题】R:data.table 中的透视和小计?【英文标题】:R: pivoting & subtotals in data.table? 【发布时间】:2019-07-16 19:08:56 【问题描述】:透视和小计是电子表格和 SQL 中常见的辅助步骤。
假设一个带有字段date, myCategory, revenue
的data.table。假设您想知道日收入占所有收入的比例以及不同子组内的日收入比例,这样
b[,
#First auxiliary variable of all revenue
totalRev = sum(revenue) #SUBGROUP OF ALL REV
#Second auxiliary variable of revenue by date, syntax wrong! How to do this?
totalRev_date=sum(revenue), by=list(date) #DIFFERENT SUBGROUP, by DATE's rev
#Within the subgroup by date and myCategory, we will use 1st&2nd auxiliary vars
.SD[,.(Revenue_prop_of_TOT=revenue/totalRev,
,Revenue_prop_of_DAY=revenue/totalRev_date) ,by=list(myCategory,date)]
,]
我们需要计算辅助总和,特定日期的所有收入和整个历史的所有收入。
最终结果应该是这样的:
date myCategory Revenue_prop_of_TOT Revenue_prop_of_DAY
2019-01-01 Cat1 0.002 0.2
...
你看到辅助变量只是帮助函数。
如何在 R data.table 中透视和计算小计?
【问题讨论】:
【参考方案1】:另一个使用data.table::cube
的选项:
cb <- cube(DT, sum(value), by=c("date","category"), id=TRUE)
cb[grouping==0L, .(date, category,
PropByDate = V1 / cb[grouping==1L][.SD, on="date", x.V1],
PropByCategory = V1 / cb[grouping==2L][.SD, on="category", x.V1],
PropByTotal = V1 / cb[grouping==3L, V1]
)]
输出:
date category PropByDate PropByCategory PropByTotal
1: 1 1 0.3333333 0.2500000 0.1
2: 1 2 0.6666667 0.3333333 0.2
3: 2 1 0.4285714 0.7500000 0.3
4: 2 2 0.5714286 0.6666667 0.4
数据:
DT <- data.table(date=c(1, 1, 2, 2), category=c(1, 2, 1, 2), value=1:4)
# date category value
#1: 1 1 1
#2: 1 2 2
#3: 2 1 3
#4: 2 2 4
【讨论】:
data.table::cube 有什么好处?这是"Calculate aggregates at various levels of groupings producing multiple (sub-)totals. Reflects SQLs GROUPING SETS operations.
的描述。
它实际上来自 sql,其中对大量聚合进行了预处理以加快后续分析。我看到你的问题是做了大量的聚合,我想到了多维数据集
我不知道立方体,更多信息here。如果您想复制 excel 数据透视表、添加小计等,这似乎很有用。
立方体很棒,groupingsets
也值得一看。如果我没记错的话,cube 可以用groupingsets
实现,因此在 R 中旋转更通用一点。+1 可以找到这个很棒的工具。
@hhh 你没记错,看看data.table:::cube.data.table
【参考方案2】:
希望我能正确理解您的意图,但如果您需要不同的输出,请在 cmets 中告诉我。
b = data.table(date = rep(seq.Date(Sys.Date()-99, Sys.Date(), "days"), each=2),
myCategory = c("a", "b"),
revenue = rnorm(100, 200))
# global total, just create a constant
totalRev = b[, sum(revenue)]
# Total revenue at myCategory and date level / total Revenue
b[, Revenue_prop_of_TOT:=sum(revenue)/totalRev, by=.(myCategory, date)]
# you can calculate totalRev_date independently
b[, totalRev_date:=sum(revenue), by=date]
# If these are all the columns you have you don't need the sum(revenue) and by calls
b[, Revenue_prop_of_DAY:=sum(revenue)/totalRev_date, by=.(myCategory, date)]
最后我会将它包装在一个函数中。
revenue_total <- function(b)
totalRev = b[, sum(revenue)]
b[, Revenue_prop_of_TOT:=sum(revenue)/totalRev, by=.(myCategory, date)]
b[, totalRev_date:=sum(revenue), by=date]
b[, Revenue_prop_of_DAY:=sum(revenue)/totalRev_date, by=.(myCategory, date)]
b
b = revenue_total(b)
【讨论】:
【参考方案3】:R 中的透视和小计选项
立方回答here
由 marbel here 评论的分组集
【讨论】:
以上是关于R:data.table 中的透视和小计?的主要内容,如果未能解决你的问题,请参考以下文章
R语言data.table导入数据实战:data.table使用dcast.data.table函数实现透视表(pivot table)