この SAS 用の SQL コードを見つけたので、RSQL Lite に変換したいと思います。
proc sql;
create table crspcomp as
select a.*, b.ret, b.date
from ccm1 as a left join crsp.msf as b
on a.permno=b.permno
and intck('month',a.datadate,b.date)
between 3 and 14;
quit;
発生した最初の問題は、R が intck 関数を提供しないことでした。これは、2 つの日付の月の差を返します。次のような同様の関数を(stackoverflowで)見つけました。
mob<-function (begin, end) {
begin<-paste(substr(begin,1,6),"01",sep="")
end<-paste(substr(end,1,6),"01",sep="")
mob1<-as.period(interval(ymd(begin),ymd(end)))
mob<-mob1@year*12+mob1@month
mob
}
RSQL の外で mob 関数をテストしましたが、今のところ問題なく動作します。さて、上記の SQL 文に mob 関数を入れたいと思います。SQL コードでは、permno でデータをマージしたいと考えています。さらに、データを 3 か月遅延させたいと考えています (これが mob 関数を使用する理由です)。
Annual_File は次のようになります。
GVKEY,datadate,fyear,fyr,bkvlps,permno
14489,19980131,1997,1,4.0155,11081
14489,19990131,1998,1,1.8254,11081
14489,20000131,1999,1,2.0614,11081
14489,20010131,2000,1,2.1615,11081
14489,20020131,2001,1,1.804,11081
CRSPファイルは次のようになります
permno,date,ret
11081,20000103,0.1
11081,20000104,0.2
install.packages('DBI')
install.packages('RSQLite')
mob<-function (begin, end) {
begin<-paste(substr(begin,1,6),"01",sep="")
end<-paste(substr(end,1,6),"01",sep="")
mob1<-as.period(interval(ymd(begin),ymd(end)))
mob<-mob1@year*12+mob1@month
mob
}
Annual_File <- "C:/Users/XYZ"
Annual_File <- paste0(Annual_File ,".csv",sep="")
inputFile <- "C:/Users/XYZ"
inputFile <- paste0(inputFile.csv",sep="")
con <- dbConnect(RSQLite::SQLite(), dbname='CCM')
dbWriteTable(con, name="CRSP", value=inputFile, row.names=FALSE, header=TRUE, overwrite=TRUE)
dbWriteTable(con, name="Annual_File", value=Annual_File, row.names=FALSE, header=TRUE, overwrite=TRUE)
DSQL <- "select a.*, b.ret, b.date
from Annual_File as a left join
CRSP as b
on a.permno=b.PERMNO
and mob(a.datadate,b.date)
between 3 and 14"
yourData <- dbGetQuery(con,DJSQL)
関数を定義するのは難しいですが、エラーは次のようになります。
Error in sqliteSendQuery(con, statement, bind.data) :
error in statement: no such function: mob