Как сгруппировать , обобщить и сделать более широкий разворот по дате?

#r

Вопрос:

У меня есть скудный набор данных

 df = structure(list(id= c("20210301168026390916", "20210301168026390916", 
"20210301168026390916"), date= c("2021-05-01", "2021-06-01", 
"2021-06-22"), usd= c(34403, 3333, 22256), provider= c("900098550", 
"900098550", "901098333")), .Names = c("id", "date", 
"usd", "provider"), row.names = c(NA, 3L), class = "data.frame")
 

Не могли бы вы посоветовать способ группировки записей по поставщику и дате и суммирования значений в долларах США, чтобы результирующая таблица была:

 Provider     2021_05    2021_06
900098550    34403        3333
901098333    0           22256
 

Спасибо

Ответ №1:

Мы можем format Date преобразовать «дату», чтобы включить только год-месяц, а затем pivot_wider изменить форму с «длинной» на «широкую», указав values_fn как sum и values_fill как 0

 library(dplyr)
library(tidyr)
df %>% 
   select(-id) %>%
   mutate(date = format(as.Date(date), '%Y-%m')) %>% 
   pivot_wider(names_from = date, values_from = usd, 
         values_fn = sum, values_fill = 0)
 

-выход

 # A tibble: 2 x 3
#  provider  `2021-05` `2021-06`
#  <chr>         <dbl>     <dbl>
#1 900098550     34403      3333
#2 901098333         0     22256
 

Или может использовать dcast from data.table (обратите внимание, что dcast with reshape2 также имеет тот же синтаксис )

 library(data.table)
dcast(setDT(df), provider ~ format(as.Date(date), '%Y-%m'), 
      value.var = 'usd', fill = 0, fun.aggregate = sum)
 

-выход

 #     provider 2021-05 2021-06
#1: 900098550   34403    3333
#2: 901098333       0   22256
 

В base R , мы можем использовать tapply

 with(df, tapply(usd, list(provider, date = format(as.Date(date), 
       '%Y-%m')), FUN = sum))
 

В дополнение к вышеперечисленным опциям, есть pivottabler , что также создает дополнительные наценки

 library(pivottabler)
df$date <- format(as.Date(df$date), '%Y-%m')   
qpvt(df, "provider", "date", "sum(usd)")
#           2021-05  2021-06  Total  
#900098550    34403     3333  37736  
#901098333             22256  22256  
#Total        34403    25589  59992  
 

Комментарии:

1. Причина, по которой я пропустил изменение формы, заключается в том, что оно не будет агрегировать/суммировать значения. Вам придется использовать transform aggregate reshape, но я мог бы использовать только transform xtabs

Ответ №2:

В базе R вы будете делать:

 xtabs(usd~provider date, transform(df, date = format(as.Date(date), "%Y-%m")))
           date
provider    2021-05 2021-06
  900098550   34403    3333
  901098333       0   22256
 

Для опции base R. Если вам нужен кадр данных, вы могли бы сделать:

  a <-  xtabs(usd~provider date, transform(df, date = format(as.Date(date), "%Y-%m")))
cbind(provider = rownames(a), as.data.frame.matrix(a, 1))
   provider 2021-05 2021-06
1 900098550   34403    3333
2 901098333       0   22256
 

Ответ №3:

Базовый вариант R с использованием reshape

 reshape(
  transform(df, date = format(as.Date(date), "%Y_%m")),
  direction = "wide",
  idvar = "provider",
  timevar = "date",
  drop = "id"
)
 

дает

    provider usd.2021_05 usd.2021_06
1 900098550       34403        3333
3 901098333          NA       22256