是否有一个 R 函数镜像 EXCEL 计数,以日期范围为条件?



>我目前面临以下问题。

我想想出一个 R 代码,在我的主数据帧中创建一个名为reviews_last30days的新列listings,该列应该能够计算或累积每个唯一listings$ID的所有评论。

每个 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

我还需要添加一个日期条件,例如,仅考虑从last_scrape开始的过去 30 天。

因此,我的结果应该有点像第三列:(更新:请参阅编辑以更好地描述预期结果)

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

因此,最后,列reviews_last30days应计算自last_scape以来每个ID的指示时间范围 30 天以来的review_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条目,其中 OVERVIEWID与REVIEWS中的ID匹配,并且REVIEWS的review_date从OVERVIEW中的last_scrape最多30天。

然后,代码应理想地将此新计算的值分配为 OVERVIEW 中的新列,如下所示:

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"

任何进一步的帮助非常感谢 - 提前感谢!

您可以使用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成为输入而不是每个组的最新审阅日期,则可以修改代码。假设每个 ID 可以有多个last_scrape

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

与上面的答案类似...

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

最新更新