R - 检查日期范围是否包含特定值,使用来自不同数据框的日期

R - Check if a range of dates contains a certain value, using dates from a different data frame

我正在开展一个项目,分析信用卡公司的利率随时间的变化以及同一时期普通信用卡公司的推文。目标是看看我们是否可以预测信用卡公司何时会根据他们的 Twitter 帐户更改利率。

我有两个数据框:1) 如果利率在给定日期发生变化 [RATES] 和 2) 推文及其创建日期 [TWEETS]。对于 TWEETS 中的每个日期,我想过滤基本上 TWEETS$DATE_CREATED - 7 到 TWEETS$DATE_CREATED 上的 RATES 数据集,并查看 RATES 数据集中在此日期范围内是否有速率变化。

现在,我正在使用 for 循环来执行此操作(呃,我知道)。它的速度非常慢,我确信这是一种在执行速度更快的单行代码中执行此 for 循环的方法。非常感谢任何帮助。

此 for 循环将 RATES 过滤到每个 TWEETS$created_date 和前 7 天,并在 TWEETS$changedToday 列中查找 1,然后将其放入 Tweets 中的新列中。

install.packages("lubridate") #dates modification package
library(lubridate)

rates.date <- mdy(c("01/01/20", "01/02/20", "01/03/20", "01/04/20"))
rate <- c(0.25, 0.25, 0.50, 0.50)
changedToday <- c(NA, 0, 1, 0)
RATES <- data.frame(rates.date, rate, changedToday) #mdy() converts string to date as month day year

tweets.date <- mdy(c("01/02/20", "01/10/20"))
text <- c("Tweet 1", "tweet 2")
TWEETS <- data.frame(tweets.date, text)


for (i in c(1:nrow(TWEETS))) {
  TWEETS$changedInLast7[i] = any(filter(RATES, TWEETS$tweets.date[i] - days(7) < RATES$rates.date & RATES$rates.date <= TWEETS$tweets.date[i])$changedToday==1)
}

**RATES**
rates.date    rate  changedToday
1/1/20        0.25  NA
1/2/20        0.25  0
1/3/20        0.50  1 # 1 since it is different from yesterday
1/4/20        0.50  0

**TWEETS**
tweets.date   text
1/2/20        "tweet 1"
1/10/20       "tweet 2"

**GOAL**
*TWEETS*
tweets.date   text       changeInLast7
1/2/20        "tweet 1"  FALSE
1/10/20       "tweet 2"  TRUE

for 循环的替换可以用 sapply 完成:

TWEETS$changedInLast7 <- sapply(TWEETS$tweets.date, function(x)
                         any(with(RATES, (x - 7) <= rates.date & 
                         rates.date <= x & changedToday == 1), na.rm = TRUE))

tidyverse 方式是:

library(dplyr)

tidyr::crossing(TWEETS, RATES) %>%
    group_by(tweets.date, text) %>%
    summarise(changeInLast7 = any(between(rates.date, first(tweets.date) - 7, 
                          first(tweets.date)) & changedToday == 1, na.rm = TRUE))


# tweets.date   text    changeInLast7
#  <date>      <fct>   <lgl>        
#1 2020-01-02  Tweet 1 FALSE        
#2 2020-01-10  tweet 2 TRUE     

我们可以使用

TWEETS$changedInLast7 <- unlist(lapply(TWEETS$tweets.date, function(x)
                     any(with(RATES, (x - 7) <= rates.date & 
                     rates.date <= x & changedToday == 1), na.rm = TRUE)))