非常感谢你的评论/回答。
背景信息:我有一个包含十几个国家/地区掉期汇率每日价格的大型数据表。列是[ID,Date,X1Y,X2Y,X3Y ... X30Y],其中X..Y是表示收益率曲线部分的列(例如,X1Y是1年交换,X3Y是3年交换)。这两个键是 ID (例如“AUD”,“GBP”)和 Date (例如“2001-04-13”,“2001-04-16”)。
虚拟数据:
set.seed(123)
dt <- cbind(ID=rep(c("AUD","GBP"),c(100,100)),X1Y=rnorm(200),X2Y=rnorm(200),X3Y=rnorm(200))
dt <- data.table(dt)
dt[,Date := seq(from=as.IDate("2013-01-01"), by="1 day", length.out=100)]
setkeyv(dt,c("ID","Date"))
问题1: 首先生成一些虚拟信号。如果有100列具有相当复杂的信号生成公式,在单独的函数中编写genSig(X1Y),那么语法是什么?这就是我的意思,只使用3列和一些无意义的公式:
dt[,SIG1 :=c(0, diff(X1Y ,1)),by="ID"]
dt[,SIG2 :=c(0, diff(X2Y ,1)),by="ID"]
dt[,SIG3 :=c(0, diff(X3Y ,1)),by="ID"]
问题2: 根据“月中”推进列。例如,使用SIG列,我想在每个月的15日之后做出与15日信号相同的所有内容,直到下个月的15日。棘手的是,实际数据只包含交易日,所以如果是周末/假日,有些月份不会有15日。另一个问题是使用有效的语法,我可以在每个月的开始使用循环(我知道..)来实现类似的东西,只是为了表明我的意思:
for (i in 2:length(dt$Date)){
if(as.POSIXlt(dt[i,]$Date)$mon == as.POSIXlt(dt[i-1,]$Date)$mon){
dt[i, SIG1 := dt[i-1,SIG1]]
dt[i, SIG2 := dt[i-1,SIG2]]
dt[i, SIG3 := dt[i-1,SIG3]]
}
}
我无法弄清楚如何处理“月中”问题,因为它可能会落在15或16或17日。与问题1一样,如果有一种智能方式可以插入/更新多个/十几列,我们将不胜感激。
答案 0 :(得分:2)
就问题2而言,您可以使用滚动连接:
# small sample to demonstrate
dt = data.table(date = as.Date(c('2013-01-01', '2013-01-15', '2013-01-17', '2013-02-14', '2013-02-17'), '%Y-%m-%d'), val = 1:5)
dt
# date val
#1: 2013-01-01 1
#2: 2013-01-15 2
#3: 2013-01-17 3
#4: 2013-02-14 4
#5: 2013-02-17 5
setkey(dt, date)
midmonth = seq(as.Date('2013-01-15', '%Y-%m-%d'),
as.Date('2013-12-15', '%Y-%m-%d'),
by = '1 month')
dt[, flag := 0]
dt[J(midmonth), flag := 1, roll = -Inf]
dt
# date val flag
#1: 2013-01-01 1 0
#2: 2013-01-15 2 1
#3: 2013-01-17 3 0
#4: 2013-02-14 4 0
#5: 2013-02-17 5 1
现在您可以cumsum
flag
获取您想要的分组,例如做:
dt[, val1 := val[1], by = cumsum(flag)]
dt
# date val flag val1
#1: 2013-01-01 1 0 1
#2: 2013-01-15 2 1 2
#3: 2013-01-17 3 0 2
#4: 2013-02-14 4 0 2
#5: 2013-02-17 5 1 5
答案 1 :(得分:1)
# problem 1
nsig <- 3L
csig <- 1:nsig+1L
newcols <- paste('SIG',1:nsig,sep='')
dt[,(newcols):=0]
for (j in csig) set(dt,j=j+nsig+1L,value=c(0, diff(dt[[j]],1)))
在看了@ eddi的回答之后,我发现set
对问题2没那么有用。这就是我要做的事情:
dt[,(newcols):=lapply(newcols,function(x) get(x)[1]),by=list(ID,month(Date-14))]
根据this answer,您可以通过这种方式从日期中减去天数。
除了。 Cbinding矢量构成一个矩阵。在您的示例中,您有一个字符矩阵。我想你在找......
# Creating better data...
set.seed(123)
dt <- data.table(ID=rep(c("AUD","GBP"),c(100,100)),
X1Y=rnorm(200),X2Y=rnorm(200),X3Y=rnorm(200),
Date=seq(from=as.IDate("2013-01-01"), by="1 day", length.out=100))