Использование пакета runner для обобщения групп

#r #runner

#r #runner

Вопрос:

У меня есть таблица цен на жилье и дат продажи. Я хочу рассчитать скользящую среднюю цену за период времени в 365 дней, используя пакет runner. Мне нужна только одна средняя цена за дату.

Моя проблема в том, что когда я пробую приведенный ниже код, я получаю более одной средней цены за дату, если эта дата появляется более одного раза. Это не то, чего я ожидал. Я думал, что будет один результат за каждый день, если я использую group_by /summarise.

 library(runner)
library(tidyverse)
library(lubridate)

startDate = as_date("2018-01-01")
endDate = as_date("2020-01-01")

# Create data
soldData <- tibble(
  price = round(rnorm(100, mean=500000, sd=100000),-3),
  date = sample(seq.Date(startDate,endDate,by="days"),100,replace=T))

# Fill in the missing dates between startDate and endDate
soldData <- bind_rows(soldData,anti_join(tibble(date=seq.Date(startDate,endDate,by="day")),soldData)) %>%
  arrange(date)

# Find the duplicated dates
duplicatedDates <- soldData[duplicated(soldData$date),]$date

# I thought using group_by/summarise would return one medianPrice per date
results <- soldData %>%
  group_by(date) %>%
  summarise(medianPrice = runner(
    price,
    k = "365 days",
    idx = date,
    f = function(x) {median(x,na.rm=T)})) 

# These are the problem rows.
duplicatedResults <- results %>%
  filter(date %in% duplicatedDates)
  

Есть идеи, где я ошибаюсь?

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

1. Когда вы group_by встречаетесь, не остается наблюдений, которые можно продолжить. Попробуйте сгруппировать по чему-то другому или не группируйте, как предложил @Ronak Shah.

Ответ №1:

Начиная с dplyr 1.0.0, вы можете получать выходные данные, возвращающие несколько строк из summarise .

Сначала вам нужно разобраться с дублирующимися данными, которые у вас уже есть в ваших данных. Что вы хотите сделать с датами, которые встречаются несколько раз? Одним из способов было бы взять median / mean из них.

 library(dplyr)
library(runner)

soldData %>%
  group_by(date) %>%
  summarise(price = median(price, na.rm = TRUE)) -> df
  

Итак, теперь в df у нас есть только одно значение для каждой date . Теперь вы можете применить runner функцию.

 df %>%
    mutate(medianPrice = runner(price,
                                k = "365 days",
                                idx = date,
                                f = function(x) {median(x,na.rm=T)})) 
  

Также есть zoo:rollmedianr который помогает в вычислении скользящей медианы.