2010-11-05 19 views
2

-edited爲clarity-如何使用的,而()函數在一個時間,直到我發現最後一欄的最後一行指標達到評價矩陣一行<0

我感興趣的是找到多維自相關函數的零點。

我可以用

acm <- autocorr(x, 1:10) 

然而,全矩陣可以是20×5000的順序生成從我的數據的自相關矩陣,這是計算昂貴。

因此,我一次只計算1或n行。

這裏是我想借此

  1. 計算在矩陣中的第一行中的步驟
  2. 而(任何列具有所有正值) 計算和矩陣的下一行追加到已計算的行
  3. 確定的最後一列的行指數達到零

如果這是全矩陣:

acm <- cbind(c(10, 9, 8, 7, 6, 5, 4, 3, 1, -1), 
       c(10, 8, 6, 5, 3, 1, -1, 1, -1, 0)) 

我想要一個函數返回10,因爲第一個col是最後一個達到負值。如果我先計算完整矩陣,則以下就足夠了:

max(which(apply(acm, 2, min))) 

但是我想避免計算比所需的更多的acm,因爲往往只有1或一小部分的行是必要的計算。

+1

您的acm格式不正確,您的功能解決方案無法正常工作:應用不會產生合乎邏輯的結果。 – 2010-11-08 16:39:55

+0

對不起,這些載體的長度不同,但我已經解決了這個問題。 – 2010-11-08 17:34:54

回答

0

我不知道到底是什麼你的函數是做,但要回答這個問題:「我如何才能找到其中的列值低於零動態生成矩陣的最後一排?」:

findlastzero = function(mat){ 
    apply(mat<0, 2, function(x)tail(which(x),1)) 
    } 

set.seed(1) 
a <- cbind(rnorm(10), rnorm(10), rnorm(10), rnorm(10)) + 0.5 

a 

      [,1]  [,2]  [,3]  [,4] 
[1,] -0.1264538 2.0117812 1.41897737 1.85867955 
[2,] 0.6836433 0.8898432 1.28213630 0.39721227 
[3,] -0.3356286 -0.1212406 0.57456498 0.88767161 
[4,] 2.0952808 -1.7146999 -1.48935170 0.44619496 
[5,] 0.8295078 1.6249309 1.11982575 -0.87705956 
[6,] -0.3204684 0.4550664 0.44387126 0.08500544 
[7,] 0.9874291 0.4838097 0.34420449 0.10571005 
[8,] 1.2383247 1.4438362 -0.97075238 0.44068660 
[9,] 1.0757814 1.3212212 0.02184994 1.60002537 
[10,] 0.1946116 1.0939013 0.91794156 1.26317575 


findlastzero(a) 
[1] 6 4 8 5 

不知道這是你所要求的不過對於..

+0

謝謝,關閉,但我試圖找到最後有一個負數的行的索引;而不是一次檢查整個矩陣,從n行的子集開始,並且如果有一些行未達到零,則添加另外n行並進行測試。問題是可能需要幾分鐘來計算整個矩陣,前50行通常會有一個<0的數字,但有時可能需要幾千行。 – 2010-11-06 02:29:44

0

不知道如果我理解正確你的問題,但你可以使用tapply的Elid來向每個行的矩陣中提取你想要的信息。

我首先創建一個與您的a大小相同的「分組矩陣」。 這可以作爲將每行作爲輸入分組到您的lambda函數中的索引。

matrix(rep(1:10,4),nrow=10,ncol=4) 

然後,我用分組矩陣在原始矩陣上運行「tapply」。此子集的矩陣,使得每個行矢量被傳遞到功能:

function(x) { return(x[which(x<0)]) } 

它簡單地返回所有值,其中值小於零每行。

> a 
      [,1]  [,2]  [,3]  [,4] 
[1,] 0.5341781 -0.9263866 -0.5380141 -1.2453310 
[2,] 0.2931630 1.0490300 0.8127472 0.2473263 
[3,] 1.0936143 -0.3399709 1.8199833 1.0053080 
[4,] 1.0002433 0.2002659 1.7730118 1.7578414 
[5,] 0.8116914 0.9371518 0.8727981 1.4236349 
[6,] -0.1127914 1.1563594 1.0331311 0.7658510 
[7,] -0.5423493 1.8905533 -0.8121652 0.1355076 
[8,] -1.6589310 0.4081290 0.3560005 1.6043205 
[9,] 1.8760435 0.8826245 1.4457357 0.7561550 
[10,] -0.8503400 0.2302597 0.5838986 0.1252952 
> matrix(rep(1:10,4),nrow=10,ncol=4) 
     [,1] [,2] [,3] [,4] 
[1,] 1 1 1 1 
[2,] 2 2 2 2 
[3,] 3 3 3 3 
[4,] 4 4 4 4 
[5,] 5 5 5 5 
[6,] 6 6 6 6 
[7,] 7 7 7 7 
[8,] 8 8 8 8 
[9,] 9 9 9 9 
[10,] 10 10 10 10 
> tapply(a, matrix(rep(1:10,4),nrow=10,ncol=4), function(x) { return(x[which(x<0)])}) 
$`1` 
[1] -0.9263866 -0.5380141 -1.2453310 

$`2` 
numeric(0) 

$`3` 
[1] -0.3399709 

$`4` 
numeric(0) 

$`5` 
numeric(0) 

$`6` 
[1] -0.1127914 

$`7` 
[1] -0.5423493 -0.8121652 

$`8` 
[1] -1.658931 

$`9` 
numeric(0) 

$`10` 
[1] -0.85034 
1

有一個使用break函數的循環解決方案。這是一個使用索引和向量tt的黑客來跟蹤哪些列已顯示負值。

find.point <- function(x){ 
    tt <- rep(F,ncol(x))   # control vector tt 

    for (i in 1:nrow(x)){ 
     tt[which(x[i,]<0)] <- T # check which columns have negative value 
     if(all(tt)) break  # if all have reached negative, get out of loop 
    } 
    i       # return index 
} 

輸出是一樣的oneliner

max(apply(acm<0,2,function(x) match(T,x))) 

你想指的是你的問題,我相信。我真的不知道你的性能問題來自哪裏。這取決於您是否有5000列或5000行。

時序:

> acm <- matrix(rep(seq.int(5000,-5999),100),ncol=22) 

> dim(acm) 
[1] 50000 22 

> system.time(max(apply(acm<0,2,function(x) match(T,x)))) 
    user system elapsed 
    0.05 0.00 0.05 

> system.time(find.point(acm)) 
    user system elapsed 
    0.05 0.00 0.05 

然而,時間大致與在oneliner當功能得到改善。在任何情況下,即使一個數據集採用oneliner十倍大,計算髮生中的第二對我來說你有多少列:

> acm <- matrix(rep(seq.int(5000,-5999),100),ncol=50000) 

> dim(acm) 
[1] 22 50000 

> system.time(max(apply(acm<0,2,function(x) match(T,x)))) 
    user system elapsed 
    0.85 0.01 0.86 

> system.time(find.point(acm)) 
    user system elapsed 
    0.03 0.00 0.04 

哎呀,你逼我想出一個for循環解決方案,效果要比oneliner更快。很酷的問題!

+0

這是一個不錯的解決方案。我沒有意識到這樣做會更快,但證明這一點很重要。性能問題來自使用來自尾聲包的autocorr.diag()計算自相關矩陣,其在相當快速的服務器上可能花費超過50秒,例如, acf < - autocorr.plot(mcmc.object) – 2010-11-08 17:32:14

+1

@David:所以實際上你想要一行一行地計算自相關矩陣......哦,男孩,這將是一個艱難的。你可能想在stats.stackexchange.com上嘗試一個。這應該是可能的,但我現在無法真正想出快速解決方案。 – 2010-11-08 17:48:10

+0

是或分段。我有一個相關的問題,要求提供更一般的解決方案,我的建議答案已合併您的代碼,已經在stats.stackexchange上:http://stats.stackexchange.com/q/4258/1381 – 2010-11-08 17:58:51

相關問題