将 Data.Tables (R) 与循环或 mapply 组合
Combining Data.Tables (R) with a loop or mapply
我是 R 中数据表的新手,我的分析已经完成了 80%。背景是我想得到一个股票5天(前后)的returns,然后在他们报告后的25天和45天。我已经成功地为一组日期(有效地硬编码)做到了,但是当我尝试自动化这个过程时,它就崩溃了。
我将从我现在的公式开始,然后解释数据。
这个公式成功地查看了数据表和 returns 我需要的总和。问题是 datem5 和 V1 需要通过一个循环(或 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")
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(就是股票的对数returns)由:
组成
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 )]
现在的问题是总和似乎没有正确计算。可能跟“可变”变量有关
而不是使用 mapply
或 for
循环,尝试使用 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))
我是 R 中数据表的新手,我的分析已经完成了 80%。背景是我想得到一个股票5天(前后)的returns,然后在他们报告后的25天和45天。我已经成功地为一组日期(有效地硬编码)做到了,但是当我尝试自动化这个过程时,它就崩溃了。
我将从我现在的公式开始,然后解释数据。
这个公式成功地查看了数据表和 returns 我需要的总和。问题是 datem5 和 V1 需要通过一个循环(或 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")
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(就是股票的对数returns)由:
组成 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 )]
现在的问题是总和似乎没有正确计算。可能跟“可变”变量有关
而不是使用 mapply
或 for
循环,尝试使用 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))