不确定do.call()在R中做了什么

时间:2014-07-08 02:46:25

标签: r

所以我是R的新手,我试图通过避免for循环来构建相关矩阵。我在网上到处搜索,我似乎无法弄清楚do.call()在我的特定情况下做了什么。你们中的一些人可能会建议我尝试使用lapply或sapply,但是在这里我只想理解为什么do.call()正在工作。

我的初步方法如下,简单且次优: (Master是一个包含价格数据的data.frame,第一列是Date,这就是我排除它的原因。)

for(i in 1:length(names(Master)[-1]))
{
  for(j in 1:length(names(Master)[-1]))
  {
    MasterVCV[i,j] <- cor(Master[,1+i],Master[,1+j],use="pairwise.complete.obs",method="pearson")
  }

}

然而,由于某些我无法弄清楚的原因,这也有效:

matrix(
  data=do.call(function(X){cor(Master[,as.character(X)],Master[,as.character(X)],use="pairwise.complete.obs",method="pearson")},list(names(Master)[-1]))
  ,nrow=length(names(Master)[-1])
  ,ncol=length(names(Master)[-1])
  ,dimnames=list(names(Master)[-1],names(Master)[-1])
)

当我只传递一个列表时,我不确定为什么/如何构建对来创建方阵。我的猜测是它在索引中进行交叉连接,但我无法在任何地方找到任何文档。任何帮助/反馈将非常感谢。如果需要任何其他细节,请告诉我。

谢谢,

编辑:添加测试用例(我希望这样做并且是适当的格式) - 从quandl下载数据

library(quantmod)
library(Quandl)


FFFactors <- Quandl("KFRENCH/FACTORS_D",type = "raw", start_date="2001-01-01", end_date = "2010-01-01")
MOM <-  Quandl("KFRENCH/MOMENTUM_D",type = "raw", start_date="2001-01-01", end_date = "2010-01-01")

FFFactors<-data.frame(Date=FFFactors[,1],sapply(FFFactors[,-1],function(X){X/100}))
MOM<-data.frame(Date=MOM[,1],MOM=MOM[,length(MOM)]/100)



Master<-merge(FFFactors,MOM,by.x="Date",by.y="Date",all.x=TRUE,all.y=TRUE)

#Recode and clean
Master$Curve[Master$Curve==Inf]<-NA
Master$Curve[Master$Curve==-Inf]<-NA
Master$Curve[Master$Curve==NaN]<-NA



##########ALTERNATIVE VCV CALC#############

  MasterVCV2<-
    matrix(
      data=do.call(function(X){cor(Master[,as.character(X)],Master[,as.character(X)],use="pairwise.complete.obs",method="pearson")},list(names(Master)[-1]))
      ,nrow=length(names(Master)[-1])
      ,ncol=length(names(Master)[-1])
      ,dimnames=list(names(Master)[-1],names(Master)[-1])
    )



#dimension VCV and create it
MasterVCV<-matrix(nrow=length(names(Master)[-1]),ncol=length(names(Master)[-1]),dimnames=list(names(Master)[-1],names(Master)[-1]))

  for(i in 1:length(names(Master)[-1]))
  {
    for(j in 1:length(names(Master)[-1]))
    {
      MasterVCV[i,j] <- cor(Master[,1+i],Master[,1+j],use="pairwise.complete.obs",method="pearson")
    }

  }

identical(MasterVCV,MasterVCV2)

1 个答案:

答案 0 :(得分:1)

首先,如果你想要一个相关矩阵,你就不必跳过所有这些火热的箍(至少不在R中)。

cor(Master[,-1],use="pairwise.complete.obs",method="pearson")

会为你做的 - 例如如果将矩阵传递给cor(...),则会得到每列与每列其他列的相关矩阵。在这里,我们通过所有列,但第一个。这也与您使用do.call(...)获得意外结果的原因有关。

你的论点:

list(names(Master)[-1])

是一个包含一个元素的列表,其中包含所有名称的向量。所以你的表达:

do.call(function(X) {...}, list(names(Master)[-1]))

基本上将包含所有相关列名的向量传递给您的函数,该函数将其传递给cor(...),如下所示:

cor(Master[,names(Master)[-1]],Master[,names(Master)[-1]],...)

反过来一步计算完整的相关矩阵。

最后一点说明。表达式:

as.list(names(Master)[-1])

创建一个包含ncol(Master)-1元素的列表,每个元素包含一列的名称。在do.call(...)中使用它会产生错误,因为你的函数没有设置为获取参数列表。