#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