R: сводные и промежуточные итоги в data.table?

Сведение и промежуточные итоги являются распространенными вспомогательными шагами в электронных таблицах и SQL.

Предположим, что таблица данных с полями date, myCategory, revenue. Предположим, вы хотите узнать долю дневной выручки от всей выручки и долю дневной выручки в разных подгруппах, чтобы

 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?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
235
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Надеюсь, я правильно понимаю, что вы имеете в виду, но, пожалуйста, дайте мне знать в комментариях, если вам нужен другой результат.

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)
Ответ принят как подходящий

Другой вариант использования 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..

hhh 18.07.2019 08:30

на самом деле он исходит из sql, где многие агрегаты предварительно обрабатываются для ускорения последующего анализа. я вижу, что ваша проблема заключается в том, что вы выполняете много агрегации, и куб пришел на ум

chinsoon12 18.07.2019 09:04

Я не знал о кубе, подробнее здесь. Кажется, это полезно, если вы хотите воспроизвести сводные таблицы Excel, добавить промежуточные итоги и т. д.

marbel 18.07.2019 17:28

Куб фантастический, а еще groupingsets есть на что посмотреть. Если я правильно помню, куб можно реализовать с помощью groupingsets, поэтому он немного более общий для поворота в R. +1 за поиск этого замечательного инструмента.

hhh 14.01.2020 08:20

@hhh вы правильно помните, взгляните на data.table:::cube.data.table

jangorecki 17.01.2020 09:33

Опции сводки и промежуточных итогов в R

  1. куб ответил здесь

  2. наборы групп прокомментировал marbel здесь

Другие вопросы по теме