2014-01-08 46 views
0

我認爲我的問題對於普通的R用戶來說非常簡單。在R中創建一個循環變量

編輯: 我的例子可能是我的真正問題的簡化版本: 請看下面的代碼:

library(markovchain) 

#create a new MC with transition matrix transitionMatrix 
mcStaticPool <- new("markovchain", states=c("perf", "def", "prep"), 
        transitionMatrix=matrix(data=c(0.89715, 0.01475, 0.08810, 0, 1, 0, 0, 0, 1), 
              byrow=TRUE, nrow=3), name="StaticPool") 
#display transition matrix 
#print(mcStaticPool) 
show(mcStaticPool) 

#initially all loans are performing 
initialState<-c(1,0,0) 
nYears<-10 

for(i in 1:nYears){ 
    afterNYears<-initialState*(mcStaticPool^i) 
    print(afterNYears) 
} 

我想這在載體中。實際上只有數字。而不是國家。

 perf  def prep 
[1,] 0.89715 0.01475 0.0881 
      perf  def  prep 
[1,] 0.8048781 0.02798296 0.1671389 
      perf  def  prep 
[1,] 0.7220964 0.03985491 0.2380487 
      perf  def  prep 
[1,] 0.6478288 0.05050584 0.3016654 
      perf  def  prep 
[1,] 0.5811996 0.06006131 0.3587391 
      perf  def  prep 
[1,] 0.5214232 0.06863401 0.4099428 
      perf  def  prep 
[1,] 0.4677948 0.076325 0.4558802 
      perf  def  prep 
[1,] 0.4196821 0.08322497 0.4970929 
      perf  def  prep 
[1,] 0.3765178 0.08941528 0.5340669 
     perf  def  prep 
[1,] 0.337793 0.09496892 0.5672381 

以下循環:

for(i in 1:10){ 
    test<-2*(2^i) 
    print(test) 
} 

這給:

[1] 4 
[1] 8 
[1] 16 
[1] 32 
[1] 64 
[1] 128 
[1] 256 
[1] 512 
[1] 1024 
[1] 2048 

我想這個保存爲一個變量,例如叫test2的。

我嘗試這樣做:

for(i in 1:10){ 
    test<-2*(2^i) 
    test2 <- print(test) 
} 

但隨後給出:

> test2 
[1] 2048 

但我想在test2的整個序列:

[1] 4 
[1] 8 
[1] 16 
[1] 32 
[1] 64 
[1] 128 
[1] 256 
[1] 512 
[1] 1024 
[1] 2048 

感謝, 最好的問候,

+0

你不能都在一個單一的載體。你的意思是數據框?也許三個向量,每個'perf','def','prep'? –

+0

也許我不清楚,我只是想把百分比作爲一個向量。應該看起來像這樣:c(0.0881,0.89715,0.01475,0.1671389,0.8048781,0.02798296,0.22380487,0.7220964,0.03985491,0.3016654,0.66478288,0.05050584,0.3587391,0.5811996,0.06006131,0.4099428,0.5214232,0.06863401,0.4558802,0.4677948,0.076325,0.4970929 ,0.4196821,0.08322497,0.5340669,0.3765178,0.08941528,0.5672381,0.3337793,0.09496892) –

回答

1

正如其他人所提到的,你可以將這個向量化,但是如果你正在做一些更復雜的事情,而不是像這樣向量化,那麼還有其他的選擇。

當您的主要目標是根據每次迭代的結果創建一個向量(或矩陣或數組)時,它通常會更好/更簡單/更清晰/等等。使用sapply函數(或其他相關函數)而不是顯式循環。

例如:

test2 <- sapply(2:11, function(x) 2*(2^i)) 

如果確實需要一個環路,則最好是預先分配向量(或矩陣,陣列,列表,等等),並分配到載體(或其他結構)。

下面是一些基準來比較方法(我增加了迭代賺取差價更清晰):

> library(microbenchmark) 
> 
> out <- microbenchmark( 
+ bad={test2 <- NULL; for(i in 1:10000) test2 <- c(test2,2*(2^i))}, 
+ good={test2 <- numeric(10000); for(i in 1:10000) test2[i] <- 2*(2^i) }, 
+ better={test2=sapply(1:10000, function(x) 2*(2^x))}, 
+ best={test2=2*(2^(1:10000))}) 
> out 
Unit: microseconds 
    expr  min   lq  median   uq  max neval 
    bad 172508.454 174738.8165 176630.910 197765.369 211581.875 100 
    good 26387.491 27683.0960 28150.475 28567.769 52588.194 100 
better 20645.118 21288.8155 22140.853 23022.652 49513.799 100 
    best 719.234 763.1595 768.086 773.628 1622.381 100 
> plot(out) 
> 
2

您應該簡單地這樣做:

test2 <- 2^(2:11) 

test2 <- 2*2^(1:10)test2 <- 2^(1:10+1),兩者表現出更好的你想要做什麼。

但如果你真的想用一個循環,這樣做:

test2 <- numeric(10) 
for(i in 1:length(test2)) { 
    test2[i] <- 2*(2^i) 
} 
1

一般規則:如果你發現自己使用for環R中,你是最有可能是錯誤的路線上;)

矢量化時可能

test <- 2^2:11 

如果您在使用for循環,你應該堅持做

test <- NULL 
for (i in 2:11) 
    test <- c(test, 2^i) 

,或者爲了避免每次

test <- numeric(10) 
for (i in 1:10) 
    test[i] <- 2^(i+1) 

你的代碼,你每次都覆蓋測試相同的值,而不是串聯的其他權力,只有在2048價值最終分配內存2你去。

+0

請注意,OP正在執行'2 *(2^i)'而不是'(2^i)'。另外,是不是'test < - c(test,2^i)'實際上覆蓋變量? –

+0

@JuliánUrbano:不,它不是,它將變量連接到自身。更正公式:) – nico

+0

據我瞭解,它通過連接創建一個新值,然後將該值賦值給變量'test',覆蓋它以前的任何值 –