我正试图根据矩阵a的值计算矩阵B(每列)的条件标准偏差。
#conditional function
foo<-function(x,y)
{
out<-sd(y[abs(x)==1])
return(out)
}
#create the matrix
A<-matrix(data=c(1,-1,0,1,0,0,0,0,1,1),nrow=5,ncol=2)
B<-matrix(data=c(3,4,5,6,7,8,9,10,11,12),nrow=5,ncol=2)
#run for the first column
foo(A[,1],B[,1])
#run for both columns
apply(X=A, MARGIN=2, FUN=function(x,y) foo(x,y), y=B)
正确的答案是1.53和0.707,当我直接为每列单独运行foo时,我得到了这个答案。
然而,当我尝试用apply运行这两列时,我得到的结果是3.06.2.94。
任何关于如何更改应用程序以使其工作的想法,因为我有一个大的资产矩阵(在xts对象中)。目前,我正在使用for循环,但我相信可以用更有效的方法来完成。
提前谢谢你,
Nikos
您的方法的问题在于,您正试图将矩阵(B
)传递给函数foo
,该函数需要两个向量(x
和y
)。
你可以试试这样的东西:
sapply(1:ncol(A), function(i) sd(B[as.logical(abs(A[,i])),i]))
[1] 1.5275252 0.7071068
这基本上只是一个循环。。。
另一种方法是,如果A
和B
对象是数据帧,则可以使用mapply
:
A <- as.data.frame(A)
B <- as.data.frame(B)
mapply(foo, A,B)
V1 V2
1.5275252 0.7071068
以这两种方法为基准,sapply
路线的速度可能是前者的两倍。我可以想象,这是因为sapply
只是将整数向量作为自变量并处理矩阵,而mapply
方法则将数据帧作为自变量(数据帧比矩阵慢,传递循环的信息比单个索引值多)。详细信息:
Unit: microseconds
expr min lq median uq max neval
sapply(1:ncol(A), function(i) sd(B[as.logical(abs(A[, i])), i])) 101.997 110.080 113.929 118.5480 1515.319 1000
mapply(foo, A2, B2) 191.292 200.529 207.073 215.1555 1707.380 1000