>我目前面临以下问题。
我想想出一个 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)