在R中创建循环中的变量

时间:2014-01-08 16:14:38

标签: r variables for-loop

我认为我的问题对于普通的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

谢谢, 最好的问候,

3 个答案:

答案 0 :(得分: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 :(得分:1)

一般规则:如果您发现自己在R中使用for循环,则很可能是在错误的路线上;)

尽可能矢量化

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的幂。

答案 2 :(得分: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)
>