Манипулирование данными.фрейм при использовании циклов и сохранении значений в списке

#r #list #dataframe #dplyr #cycle

Вопрос:

У меня есть 2 кода, которые обрабатывают и фильтруют (по дате) мои данные.фрейм, и они отлично работают. Теперь я хочу запускать код не только на один день, но и на каждый день в векторе:

 seq(from=as.Date('2020-03-02'), to=Sys.Date(),by='days')` #.... 538 days
 

Код, который я хочу запустить в течение всех дней между 2020-03-02 и сегодняшним днем, таков:

   KOKOKO <- data.frame %>%
          filter(DATE < '2020-03-02')%>%
          summarize(DATE = '2020-03-02', CZK = sum(Objem.v.CZK,na.rm = T) 
        
  STAVPTF <- data.frame %>% 
          filter (DATE < '2020-03-02')%>%
          group_by(CP) %>% 
          summarize(mnozstvi = last(AKTUALNI_MNOZSTVI_AKCIE), DATE = '2020-03-02') %>%
          select(DATE,CP,mnozstvi)  %>%      
          rbind(KOKOKO)%>%
          drop_na() %>%
 

Поэтому вместо «2020-03-02» я хочу заполнить все дни, начиная с «2020-03-02», один за другим. И каждый из KOKOKO и STAVPTF, созданных для такого уникального дня, как этот, я хочу сохранить в виде отдельного фрейма данных.и все они хранятся в списке.

Ответ №1:

Мы могли бы использовать map для циклического перебора последовательности и применения кода

 library(dplyr)
library(purrr)
out <- map(s1, ~   data.frame %>%
          filter(DATE < .x)%>%
          summarize(DATE = .x, CZK = sum(Objem.v.CZK,na.rm = TRUE))
 

Поскольку этот цикл повторяется, функция сделает его чище

 f1 <- function(dat, date_col, group_col, Objem_col, aktualni_col, date_val) {
     filtered <- dat %>%
          filter({{date_col}} < date_val)
     KOKOKO <-  filtered %>%
          summarize({{date_col}} := date_val,
          CZK = sum({{Objem_col}}, na.rm = TRUE) 
        
    STAVPTF <- filtered %>%        
          group_by({{group_col}}) %>% 
          summarize(mnozstvi = last({{aktualni_col}}),
            {{date_col}} := date_val) %>%
          select({{date_col}}, {{group_col}}, mnozstvi)  %>%      
          bind_rows(KOKOKO)%>%
          drop_na()
    return(STAVPTF)
}
 

и позвоните, как

 map(s1, ~ f1(data.frame, DATE, CP, Objem.v.CZK, AKTUALNI_MNOZSTVI_AKCIE, !!.x))
 

где

 s1 <- seq(from=as.Date('2020-03-02'), to=Sys.Date(), by='days')
 

Ответ №2:

Было бы легче ответить на ваш вопрос, если бы вы привели минимальный воспроизводимый пример. Это легко сделать с помощью пакетов tidyverses reprex

Однако ваш код KOKOKO может быть переписан как простая совокупная сумма:

 KOKOKO = 
  data.frame %>% 
  arrange(DATE) %>%    # if necessary 
  group_by(DATE) %>% 
  summarise(CZK = sum(Objem.v.CZK), .groups = 'drop') %>% # summarise per DATE (if necessary)
  mutate(CZK = cumsum(CZK) - CZK)  # cumulative sum excluding current row (current DATE)
 

Даже код PPTF, вероятно, может быть переписан без итераций. Сначала найдите последнее значение AKTUALNI_MNOZSTVI_AKCIE для CP и ДАТЫ. Затем это значение присваивается следующей ДАТЕ:

 STAVPTF <-
  data.frame %>% 
  group_by(CP, DATE) %>% 
  summarise(mnozstvi = last(AKTUALNI_MNOZSTVI_AKCIE), .groups='drop_last') %>%
  arrange(DATE) %>%    # if necessary 
  mutate(DATE = lead(DATE))