2012-01-23 43 views
0

我使用矩阵在R中具有矢量化Q.我有2个Cols需要使用特定索引进行回归。数据是使用矢量化和矩阵的R中的回归

matrix_senttoR = [ ... 
        0.11 0.95 
        0.23 0.34 
        0.67 0.54 
        0.65 0.95 
        0.12 0.54 
        0.45 0.43 ] ; 
indices_forR = [ ... 
      1 
      1 
      1 
      2 
      2 
      2 ] ; 
在矩阵

Col1中是数据说MSFT和歌(3各自行)和col2上是从基准StkIndex返回,上对应的日期。数据是从Matlab发送的矩阵格式。

我目前使用

slope <- by( data.frame(matrix_senttoR), indices_forR, FUN=function(x) 
         {zyp.sen (X1~X2,data=x) $coeff[2] }  ) 
betasFac <- sapply(slope , function(x) x+0) 

我用data.frame上面我不能用cbind()返回。如果我使用cbind(),那么Matlab会提供一个错误,因为它不理解数据的格式。我从Matlab里面运行这些命令(http://www.mathworks.com/matlabcentral/fileexchange/5051)。您可以用lm替换zyp(zyp.sen)。

BY在这里很慢(可能是因为数据帧?)。有没有更好的方法来做到这一点? 150k行数据需要14secs +。我可以在R中使用矩阵矢量化吗?谢谢。

+1

如果你只是运行一个回归,为什么麻烦将代码从MATLAB传递到R?在统计工具箱里,MATLAB的'regress'函数可以做到这一点。 –

+0

对代码进行一些分析以查看放缓的位置也是一个好主意。您需要知道'by'占用了多少时间,以及您的建模函数多少,以及在MATLAB和R之间传递数据需要多少时间。 –

+0

@Richie - >这是因为我试图做非参数回归,特别是使用zyp库包。我所有的数据都在Matlab中。我唯一的选择是自己设计Theil-Sen Regressor! – Maddy

回答

0

我仍然认为你是从MATLAB过渡到R而回头过于复杂的事情。传递150k行数据必然会大大减慢速度。

zyp.sen实际上是很平凡的移植到MATLAB。在这里你去:

function [intercept, slope, intercepts, slopes, rank, residuals] = ZypSen(x, y) 
% Computes a Thiel-Sen estimate of slope for a vector of data. 

n = length(x); 

slopes = arrayfun(@(i) ZypSlopediff(i, x, y, n), 1:(n - 1), ... 
    'UniformOutput', false); 
slopes = [slopes{:}]; 
sni = isfinite(slopes); 
slope = median(slopes(sni)); 

intercepts = y - slope * x; 
intercept = median(intercepts); 

rank = 2; 
residuals = x - slope * y + intercept; 

end 


function z = ZypSlopediff(i, x, y, n) 

z = (y(1:(n - i)) - y((i + 1):n)) ./ ... 
    (x(1:(n - i)) - x((i + 1):n)); 

end 

我检查这个使用R的example(zyp.sen),它给出了相同的答案。

x = [0 1 2 4 5] 
y = [6 4 1 8 7] 
[int, sl, ints, sls, ra, res] = ZypSen(x, y) 

你应该真的做一些进一步的检查,虽然,只是为了确保。

1

这很容易被移动到一个评论,但:

有几件事情要考虑,我倾向于避免by()功能,因为它的返回值是一个时髦的对象。相反,为什么不把你的indices_forR向量添加到data.frame?

df <- data.frame(matrix_senttoR) 
df$indices_forR <- indices_forR 

的plyr包做的工作从这里:

ddply(df,.(indices_forR),function(x) zyp.sen(X1~X2,data=x)$coeff[2]) 

您可以轻松地使用multi-thread或DOMC和doSnow参数.parallel=TRUE此操作ddply。

如果速度是目标,我也会学习data.table包(它包装data.frame并且更快)。另外,我假定慢速拨号是zyp.sen()呼叫而不是by()呼叫。在多个内核上执行会加快这一点。

> dput(df) 
structure(list(X1 = c(0.11, 0.23, 0.67, 0.65, 0.12, 0.45), X2 = c(0.95, 
0.34, 0.54, 0.95, 0.54, 0.43), indices_forR = c(1, 1, 1, 2, 2, 
2)), .Names = c("X1", "X2", "indices_forR"), row.names = c(NA, 
-6L), class = "data.frame") 

> ddply(df,.(indices),function(x) lm(X1~X2,data=x)$coeff[2]) 
    indices   X2 
1  1 -0.3702172 
2  2 0.6324900 
+0

- >当执行类似 evalR('slope < - ddply(df,。(indices_forR),function(x)zyp.sen(X1〜X2,data = x)$ coeff [2])时,步骤ddply不起作用。 ');我收到一个错误:Invoke Error,Dispatch Exception:Object is static;不允许操作 – Maddy

+0

@Maddy听起来像是Matlab错误,而不是R错误。不确定'zyp.sen()'包来自哪个包,但在R本身中使用lm()''''''''''''''' – Justin

+0

- >谢谢贾斯汀。但我想现在我坚持使用zyp。它是非参数化的,我必须专门使用它。我知道这是基于matlab的错误。我不是很熟悉R,所以这个Q希望得到一个解决方案。 – Maddy