【问题标题】:R: pivoting & subtotals in data.table?R: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 中透视和计算小计?

【问题讨论】:

    标签: r data.table pivot subtotal


    【解决方案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 中的透视和小计选项

      1. 立方回答here

      2. 由 marbel here 评论的分组集

      【讨论】:

        猜你喜欢
        • 2021-11-03
        • 1970-01-01
        • 2017-05-13
        • 2013-07-13
        • 1970-01-01
        • 2019-04-07
        • 1970-01-01
        • 2017-06-18
        相关资源
        最近更新 更多