R - Проверьте, содержит ли диапазон дат определенное значение, используя даты из другого фрейма данных - PullRequest
0 голосов
/ 22 апреля 2020

Я работаю над проектом, анализирующим изменения тарифов компаний-эмитентов кредитных карт с течением времени и твиты от обычных компаний-эмитентов кредитных карт за тот же период времени. Цель состоит в том, чтобы посмотреть, сможем ли мы предсказать, когда компания, выпускающая кредитные карты, изменит свои ставки на основе своих учетных записей в Twitter.

У меня есть два фрейма данных: 1) изменилась ли процентная ставка в указанную дату [ЦЕНЫ] и 2) твиты и в какой день они были созданы [Твиты]. Для каждой даты в твитах я хочу отфильтровать набор данных RATES по существу с TWEETS $ DATE_CREATED - с 7 на TWEETS $ DATE_CREATED и посмотреть, не произошло ли изменение курса в наборе данных RATES в этом диапазоне дат.

Прямо сейчас Я использую для l oop, чтобы сделать это (тьфу, я знаю). Это невероятно медленно, и я уверен, что это способ сделать это для l oop в однострочном режиме, который работает быстрее. Любая помощь будет принята с благодарностью.

Этот параметр for-l oop фильтрует RATES по каждому из твитов $ create_date и предыдущих 7 дней и ищет 1 в столбце TWEETS $ changeToday, затем помещает его в новый столбец в твитах.

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

Ответы [ 2 ]

0 голосов
/ 22 апреля 2020

Мы можем использовать

TWEETS$changedInLast7 <- unlist(lapply(TWEETS$tweets.date, function(x)
                     any(with(RATES, (x - 7) <= rates.date & 
                     rates.date <= x & changedToday == 1), na.rm = TRUE)))
0 голосов
/ 22 апреля 2020

Замена for l oop может быть выполнена с помощью sapply:

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

A 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     
...