Как я могу суммировать значения с течением времени и вычитать их, как только они больше не нужны? - PullRequest
1 голос
/ 16 февраля 2020

Привет и извинения, если об этом уже спрашивали, я не могу ничего найти через час, поэтому я спрошу:

У меня есть данные в этом стиле (извините за ужасное форматирование, как я могу сделать это более симпатично?):

person start_time end_time amount
A   2019-10-04  2020-04-21  10
A   2019-12-10  2020-01-09  20
B   2019-11-04  2020-08-21  30
B   2019-12-10  2020-01-20  15
C   2019-12-20  2020-03-19  5

Итак, я хочу иметь возможность составить график суммы amount на человека с ggplot2 с течением времени до сегодняшнего дня (или sys_date).

Это означает, что для человека A сюжет должен показывать 10 с 2019-10-04 до 2019-12-10, а после этого он должен подскочить до 30 (10 + 20). Это до 2020-01-09 (так как это в прошлом), где сумма должна go вернуться к 10.

Аналогично, для лица B сумма должна быть 30 между 2019-11-04 и 2019-12-10, после этого должно быть 45, а к 2020-01-20 должно снизиться до 30.

Я пробовал кое-что вместе:

SumAmount <- data %>%
    group_by(person,start_time,end_time) %>%
    summarise(cumulatedAmount = sum(amount)) 

Но это не так что мне нужно ...

Большое спасибо и еще раз извиняюсь за плохое форматирование.

1 Ответ

1 голос
/ 16 февраля 2020

Вот одна идея. Мы можем рассчитать общую сумму каждой даты и затем построить общую сумму.

library(tidyverse)
library(lubridate)

dat2 <- dat %>%
  # Convert to date class
  mutate_at(vars(ends_with("time")), ymd) %>%
  # Create a date sequence and expand it
  mutate(Date = map2(start_time, end_time, seq.Date, by = 1)) %>%
  unnest(cols = Date) %>%
  # Calculate the total amount for each date
  group_by(person, Date) %>%
  summarize(amount = sum(amount))

ggplot(dat2, aes(x = Date, y = amount, color = person)) +
  geom_point() +
  geom_line()

enter image description here

Вот еще один вариант. Это тот же способ расширить фрейм данных на основе даты. После этого мы можем использовать stat_summary для построения данных.

library(tidyverse)
library(lubridate)

dat2 <- dat %>%
  # Convert to date class
  mutate_at(vars(ends_with("time")), ymd) %>%
  # Create a date sequence and expand it
  mutate(Date = map2(start_time, end_time, seq.Date, by = 1)) %>%
  unnest(cols = Date) 

ggplot(dat2, aes(x = Date, y = amount, color = person)) + 
  stat_summary(fun.y = sum, geom = "path")

enter image description here

Обновление

Это решение добавляет 0 к следующей дате последней даты для каждого человека

library(tidyverse)
library(lubridate)

dat2 <- dat %>%
  # Convert to date class
  mutate_at(vars(ends_with("time")), ymd) %>%
  # Create a date sequence and expand it
  mutate(Date = map2(start_time, end_time, seq.Date, by = 1)) %>%
  unnest(cols = Date) %>%
  # Calculate the total amount for each date
  group_by(person, Date) %>%
  summarize(amount = sum(amount))

dat3 <- dat2 %>%
  # Find the last date for each person
  filter(Date == max(Date)) %>%
  # Add one day to the last date for each person
  # Set amount to be 0
  mutate(Date = Date + 1, amount = 0)

# Combine data frames
dat4 <- bind_rows(dat2, dat3)

ggplot(dat4, aes(x = Date, y = amount, color = person)) +
  geom_point() +
  geom_line()

enter image description here

DATA

dat <- read.table(text = "person start_time end_time amount
A   '2019-10-04'  '2020-04-21'  10
A   '2019-12-10'  '2020-01-09'  20
B   '2019-11-04'  '2020-08-21'  30
B   '2019-12-10'  '2020-01-20'  15
C   '2019-12-20'  '2020-03-19'  5",
                  stringsAsFactors = FALSE, header = TRUE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...