【问题标题】:R - Check if a range of dates contains a certain value, using dates from a different data frameR - 检查日期范围是否包含某个值,使用来自不同数据框的日期
【发布时间】:2026-01-21 01:00:01
【问题描述】:

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

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

现在,我正在使用 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

【问题讨论】:

  • 更新了输入表和目标输出!

标签: r date for-loop twitter lubridate


【解决方案1】:

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     

【讨论】:

    【解决方案2】:

    我们可以使用

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

    【讨论】: