создание матрицы с суммой платежа в зависимости от даты1 (строка) и даты2 (столбец) в R - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть база данных с двумя датами (дата продажи и дата оплаты), я хотел бы создать матрицу N x M с суммой значений в зависимости от таких дат:

enter image description here

код базы данных примера здесь:

#creating base
sold_date <- as.Date(c("01-01-2019", "01-01-2019", "01-02-2019", "01-02-2019", "01-03-2019", "01-01-2019"), "%d-%m-%Y")
pay_date <- as.Date(c("01-01-2019", "01-01-2019", "01-03-2019", "01-02-2019", "01-03-2019", "01-02-2019"), "%d-%m-%Y")
value <- c(10, 3, 5, 10, 15, 20)
base <- data.frame(sold_date, pay_date, value)

как я могу это сделать?

наилучшими пожеланиями

Ответы [ 5 ]

2 голосов
/ 05 февраля 2020

A data.table подход, при котором поворот и агрегирование могут быть выполнены за один шаг:

data.table::dcast(
  setDT(base), sold_date ~ pay_date, 
  value.var = 'value', 
  fun.aggregate = sum
  )
1 голос
/ 05 февраля 2020

В данных вашего примера нет нескольких записей с одинаковыми комбинациями sold_date - pay_date, я исправил это для вас:

sold_date <- as.Date(c("01-01-2019", "01-01-2019", "01-02-2019", "01-03-2019", "01-01-2019"), "%d-%m-%Y")
pay_date <- as.Date(c("01-03-2019", "01-03-2019", "01-04-2019", "01-03-2019", "01-02-2019"), "%d-%m-%Y")
value <- c(10, 5, 10, 15, 20)
base <- data.frame(sold_date, pay_date, value)

Тогда мы можем использовать синтаксис dplyr для группировки 'sold_date' и 'pay_date' и суммируем значение переменной 'value' для каждой группы:

base %>% 
  group_by(sold_date, pay_date) %>% 
  summarise(Total = sum(value))

Если вам нужны данные в форме, как показано в исходном вопросе, мы можем использовать dplyr :: pivot_wider:

base %>% 
  group_by(sold_date, pay_date) %>% 
  summarise(Total = sum(value)) %>% 
  pivot_wider(names_from = pay_date,
              values_from = Total)
1 голос
/ 05 февраля 2020
library(tidyverse)

base %>%
  group_by(sold_date, pay_date) %>%
  summarise(value = sum(value)) %>%
  pivot_wider(names_from = pay_date, values_from = value, values_fill = list(value = 0))

# A tibble: 3 x 5
# Groups:   sold_date [3]
  sold_date  `2019-01-01` `2019-02-01` `2019-03-01` `2019-04-01`
  <date>            <dbl>        <dbl>        <dbl>        <dbl>
1 2019-01-01           10           20            0            0
2 2019-02-01            0            0            5           10
3 2019-03-01            0            0           15            0
1 голос
/ 05 февраля 2020
library(tidyverse)

base %>%
  group_by(sold_date, pay_date) %>%  # get unique pairs of dates
  summarise(value = sum(value)) %>%  # and get sum of values
  ungroup() %>%                      # forget the grouping
  spread(pay_date, value, fill = 0)  # reshape dataset

# # A tibble: 3 x 5
#   sold_date  `2019-01-01` `2019-02-01` `2019-03-01` `2019-04-01`
#   <date>            <dbl>        <dbl>        <dbl>        <dbl>
# 1 2019-01-01           10           20            0            0
# 2 2019-02-01            0            0            5           10
# 3 2019-03-01            0            0           15            0
0 голосов
/ 05 февраля 2020

Вот базовое решение R, использующее reshape + aggregate

dfout <- reshape(aggregate(value ~ sold_date + pay_date,df,sum), 
                 direction = "wide",
                 idvar = "sold_date",
                 timevar = "pay_date")

, такое что

> dfout
   sold_date value.2019-01-01 value.2019-02-01 value.2019-03-01
1 2019-01-01               13               20               NA
3 2019-02-01               NA               10                5
5 2019-03-01               NA               NA               15

Если вы хотите заполнить NA 0, затем вы добавляете dfout[is.na(dfout)] <- 0 к концу кодов сверху, так что

> dfout
   sold_date value.2019-01-01 value.2019-02-01 value.2019-03-01
1 2019-01-01               13               20                0
3 2019-02-01                0               10                5
5 2019-03-01                0                0               15

DATA

df <- structure(list(sold_date = structure(c(17897, 17897, 17928, 17928, 
17956, 17897), class = "Date"), pay_date = structure(c(17897, 
17897, 17956, 17928, 17956, 17928), class = "Date"), value = c(10, 
3, 5, 10, 15, 20)), class = "data.frame", row.names = c(NA, -6L
))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...