Существует ли функция R, отражающая EXCEL COUNTIFS с диапазоном дат в качестве условия? - PullRequest
1 голос
/ 07 мая 2019

В настоящее время я сталкиваюсь со следующей проблемой.

Я хочу предложить код R, который создает новый столбец с именем, например, reviews_last30days в моем основном фрейме данных listings, который должен иметь возможность подсчитывать или накапливать все отзывы для каждого уникального listings$ID,

Уникальные отзывы по идентификатору перечислены в другом кадре данных, например:

REVIEWS
   ID   review_date
   1    2015-12-30
   1    2015-12-31
   1    2016-10-27
   2    2014-05-10
   2    2016-10-19
   2    2016-10-22
   2    2016-10-23

Мне также нужно добавить условие даты, например, такое, чтобы только последние 30 дней, начиная с last_scrape считаются.

Следовательно, мой результат должен выглядеть примерно так, как в третьем столбце: (ОБНОВЛЕНИЕ: см. РЕДАКТИРОВАНИЕ для лучшего описания предполагаемого результата)

LISTINGS
   ID   last_scrape   reviews_last30days
   1    2016-11-15    1
   2    2016-11-15    3

Итак, наконецстолбец reviews_last30days должен считать review_date для каждого ID, поскольку указанный период времени составляет 30 дней с момента last_scape.

. Я уже отформатировал оба столбца даты "as.Date" с "%Y-% m-% d ".

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

РЕДАКТИРОВАТЬ для уточнения

Помимо указанных выше ОБЗОРОВ ввода, у меня есть второй входной фрейм данных, будь то ОБЗОР, который в настоящее время выглядит примерно так в упрощенном виде:

OVERVIEW
   ID   last_scrape
   1    2016-11-15
   2    2016-11-15
   3    2016-11-15
   4    2017-01-15
   5    2017-01-15
   6    2017-01-15
   7    2017-01-15
etc

Так что мне действительно нужен код для подсчета всех записей review_date, для которых ID из ОБЗОР совпадает с ID в ОБЗОРЫ, а review_date из ОБЗОРОВ составляет максимум 30 дней от last_scrapeв ОБЗОР.

Код должен в идеале назначить это новое вычисленное значение в качестве нового столбца в ОБЗОР, как это:

OVERVIEW
   ID   last_scrape   rev_last30days
   1    2016-11-15    1
   2    2016-11-15    3
   3    2016-11-15    ..
   4    2017-01-15    ..
   5    2017-01-15    ..
   6    2017-01-15    ..
   7    2017-01-15    ..
etc

# 2 РЕДАКТИРОВАТЬ - надеюсь, мой последний;)

Спасибо заваша помощь до сих пор @mfidino!Печать вашего последнего кода по-прежнему приводит к одной незначительной ошибке, а именно:

TOTALREV$review_date <- ymd(TOTALREV$review_date)

    TOTALLISTINGS$last_scraped.calc <- ymd(TOTALLISTINGS$last_scraped.calc)

    gen_listings <- function(review = NULL, overview = NULL){
      # tibble to return
      to_return <- review %>% 
        inner_join(., overview, by = 'listing_id') %>% 
        group_by(listing_id) %>% 
        summarise(last_scraped.calc = unique(last_scraped.calc),
                  reviews_last30days = sum(review_date >= (last_scraped.calc-30)))
      return(to_return)
    }

    REVIEWCOUNT <- gen_listings(TOTALREV, TOTALLISTINGS)

Error: Column `last_scraped.calc` must be length 1 (a summary value), not 2 

У вас есть идеи, как исправить эту ошибку?

ПРИМЕЧАНИЕ. Я использовал имена, как в моемИсходный файл, код должен быть таким же.

Если это поможет, некоторые свойства вектора last_scraped.calc:

$ last_scraped.calc   : Date, format: "2018-08-07" "2018-08-07" ...
typeof(TOTALLISTINGS$last_scraped.calc)
[1] "double"
length(TOTALLISTINGS$last_scraped.calc)
[1] 549281

и

unique(TOTALLISTINGS$last_scraped.calc)
 [1] "2018-08-07" "2019-01-13" "2018-08-15" "2019-01-16" "2018-08-14" 
"2019-01-15" "2019-01-14" "2019-01-22" [9] "2018-08-22" "2018-08-21" 
"2019-01-28" "2018-08-20" "2019-01-23" "2019-01-31" "2018-08-09" 
"2018-08-10" [17] "2018-08-08" "2018-08-16"

Любая дальнейшая помощь высоко ценится - заранее спасибо!

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Вы можете сделать это довольно легко с dplyr.Я использую lubridate::ymd() здесь вместо as.Date().

library(lubridate)
library(dplyr)

REVIEWS <- data.frame(ID = c(1,1,1,2,2,2,2),
             review_date = c("2015-12-30",
                             "2015-12-31",
                             "2016-10-27",
                             "2014-05-10",
                             "2016-10-19",
                             "2016-10-22",
                             "2016-10-23"))

REVIEWS$review_date <- ymd(REVIEWS$review_date)

LISTINGS <- REVIEWS %>% group_by(ID) %>% 
              summarise(last_scrape = max(review_date),
              reviews_last30days = sum(review_date >= (max(review_date)-30)))

Выход LISTINGS - это ожидаемый результат:

# A tibble: 2 x 3
     ID last_scrape reviews_last30days
  <dbl> <date>                   <int>
1     1 2016-10-27                   1
2     2 2016-10-23                   3

РЕДАКТИРОВАТЬ:

Если вместо этого вы заинтересованы в том, чтобы last_scrape было вводом, а не самой последней датой проверки для группы, вы можете изменить код как таковой.Предполагая, что может быть несколько last_scrape для ID:

library(lubridate)
library(dplyr)

REVIEWS <- data.frame(ID = c(1,1,1,2,2,2,2),
             review_date = c("2015-12-30",
                             "2015-12-31",
                             "2016-10-27",
                             "2014-05-10",
                             "2016-10-19",
                             "2016-10-22",
                             "2016-10-23"))

REVIEWS$review_date <- ymd(REVIEWS$review_date)

OVERVIEW <- data.frame(ID = rep(1:7, 2),
                       last_scrape = c("2016-11-15",
                                       "2016-11-15",
                                       "2016-11-15",
                                       "2017-01-15",
                                       "2017-01-15",
                                       "2017-01-15",
                                       "2017-01-15",
                                       "2016-11-20",
                                       "2016-11-20",
                                       "2016-11-20",
                                       "2017-01-20",
                                       "2017-01-20",
                                       "2017-01-20",
                                       "2017-01-20"))

OVERVIEW$last_scrape <- ymd(OVERVIEW$last_scrape)

gen_listings <- function(review = NULL, overview = NULL){
  # tibble to return
  to_return <- review %>% 
    inner_join(., overview, by ='ID') %>% 
    group_by(ID, last_scrape) %>% 
    summarise(
    reviews_last30days = sum(review_date >= (last_scrape-30)))
  return(to_return)
}

LISTINGS <- gen_listings(REVIEWS, OVERVIEW)

Выход этого объекта LISTINGS:

     ID last_scrape reviews_last30days
  <dbl> <date>                   <int>
1     1 2016-11-15                   1
2     1 2016-11-20                   1
3     2 2016-11-15                   3
4     2 2016-11-20                   2
0 голосов
/ 07 мая 2019

Аналогично ответу выше ...

REV %>% group_by(ID) %>%
  mutate(rev_latest = max(review_date)) %>%
  filter(rev_latest - review_date < 30) %>%
  count(ID)
...