Объединение Data.Tables (R) с al oop или mapply - PullRequest
2 голосов
/ 03 августа 2020

Я новичок в таблицах данных в R, и мне удалось пройти 80% анализа. Предпосылкой является то, что я хочу получить доходность акций через 5 дней (до и после), а затем через 25 и 45 дней после их отчета. Мне удалось сделать это для одного набора дат (по сути, жесткое кодирование), но когда я пытаюсь автоматизировать процесс, он разваливается.

Я начну с моих текущих формул, а затем объясню данные.

Эта формула успешно просматривает таблицы данных и возвращает нужную мне сумму. Проблема в том, что datem5 и V1 нужно от go до al oop (или mapply) для автоматизации процесса.

CQR_Date[CQR_DF[CQR_Date, sum(CQR), on = .(unit, date >= date1, date <= datem5),
            by = .EACHI], newvar := V1, on = .(unit, date1=date)]

Я пробовал это (вместе со многими другими вариантами). Обратите внимание, что необходимо указать и newvar.

for (i in 1:4) {
              CQR_Date[CQR_DF[CQR_Date, sum(CQ), on = .(unit, date >= date1, date <= cols[,..i]),
              by = .EACHI], newvar := v, on = .(unit, date1=date)]

но получаю эту ошибку

Error: argument specifying columns specify non existing column(s): cols[3]='cols[, ..i]'

Интересно, что когда я пытаюсь

for (i in 1:2) {
 y <- cols[,..i]}

Нет проблема.

Теперь с точки зрения данных;

  • col просто содержит заголовки столбцов, которые мне нужны из CQR_Data

    cols <- data.table ( «datem5», «datep5», «datep20», «datep45») </p>

CQ_Data содержит отчетные даты для стандартного CQ, например:

 CQ_Date <- data.frame("date1" = anydate(c("2016-02-17", "2016-06-12", "2016-08-17")))
 CQ_Date$datem5 <- CQ_Date$date1 - 5  # minus five days
 CQ_Date$datep5 <- CQ_Date$date1 + 5  # plus five days
 CQ_Date$datep20 <- CQ_Date$date1 + 20
 CQ_Date$datep45 <- CQ_Date$date1 + 45
 CQ_Date$unit <- 1    # I guess I need this for some sort of indexing

Затем CQ_DF (это журнал доходности акций) формируется следующим образом:

 CQ_DF <- data.frame("unit" = rep(1,300))
 CQ_DF$CQ <- rnorm(10)
 CQ_DF$date <- seq(as.Date("2015-12-25"), by = "day", length.out = 300)
 CQ_DF$unit <- 1

Перед установкой их как DT

setDT(CQ_DF)
setDT(CQ_Date)

Любая помощь будет принята с благодарностью. Обратите внимание, что здесь используется

  library(data.table)
  library(anytime)     

. Упрощенная версия:

  CQ_Date <- data.frame("date1" = c(10, 20))
  CQ_Date$datep5 <- CQ_Date$date1 + 5  # plus five days
  CQ_Date$datep20 <- CQ_Date$date1 + 10
  CQ_Date$unit <- 1 

  CQ_DF <- data.frame("unit" = rep(1,100))
  CQ_DF$CQ <- seq(1, by = 1, length.out = 100)
  CQ_DF$date <- seq(1, by = 1, length.out = 100)
  CQ_DF$unit <- 1

  setDT(CQ_DF)
  setDT(CQ_Date)

  cols <- c("datep5", "datep20" )

  tmp <- melt(CQ_Date, measure.vars = cols)
  setDT(tmp)

  tmp[CQ_DF[tmp, sum(CQ), on = .( unit, date >= date1,  date <= value), by = 
  .EACHI],newvar := V1, on = .(unit, date1=date  )]

Проблема в том, что теперь сумма работает некорректно. Это может иметь какое-то отношение к "переменной" переменной.

1 Ответ

2 голосов
/ 03 августа 2020

Вместо использования mapply или for l oop попробуйте преобразовать набор данных в длинный формат, используя melt, создать последовательность между числами, выполнить соединение и вычислить sum.

library(data.table)
cols <- c("datep5", "datep20" )

tmp <- melt(CQ_Date, measure.vars = cols)
tmp <- melt(CQ_Date, measure.vars = cols)
tmp <- tmp[, list(date = seq(date1, value)), .(unit, variable, date1, value)]
tmp <- merge(tmp, CQ_DF, by = c('unit', 'date'))
tmp[, .(newvar = sum(CQ)), .(unit, variable, date1)]

#   unit variable date1 newvar
#1:    1   datep5    10     75
#2:    1  datep20    10    165
#3:    1   datep5    20    135
#4:    1  datep20    20    275

Если вам нужны данные обратно в широком формате, вы можете использовать dcast.

Эквивалент tidyverse вариант:

library(tidyverse)

CQ_Date %>%
  pivot_longer(cols = cols) %>%
  mutate(date = map2(date1, value, seq)) %>%
  unnest(date) %>%
  left_join(CQ_DF, by = c('unit', 'date')) %>%
  group_by(unit, name, date1) %>%
  summarise(newvar = sum(CQ))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...