

非常に初歩的な質問で恐縮なのですが、ループを用いて複数のオブジェクトに処理を施す方法に関して質問があります。

[code]

    x1, x2, x3, ... ,xn
    
[/code]

というxtsオブジェクトがあるとき、

[code]

    vx1, vx2, ..., vxn
    
[/code]

という複数のベクトルをつくろうとして

[code]

    i <- 1
    for (i in 1:n)
    {
     vx[i] <- as.vector(x[i])
     i <- i+1
    }
    
[/code]

としてみました。がうまくいきませんでした。 コードに誤りや勘違いがありましたらご指摘お願いします。


CC BY-SA 3.0
2014-12-28T05:14:51.840
2720
2015-01-04T03:13:35.047
2014-12-28T05:47:07.393
33
5850
question
r
R言語におけるループでの複数のオブジェクトの処理


質問を字面通りに受け取ると、

`x1`と`vx1`が存在していて、これは配列やリストではないということなのでしょうから、 そのままでは添字でアクセスできません。

なので一旦listなどにしてあげる必要があるんじゃないでしょうか。例えば、こんな感じですかね。

[code]

    require("xts")
    data(sample_matrix)
    x1 <- as.xts(sample_matrix)
    # is.xts(x1)
    x2 <- as.xts(sample_matrix)
    x3 <- as.xts(sample_matrix)
    
    n <- 3
    xlst <- list(x1, x2, x3)
    
    vx <- array(1:n)
    for( i in 1:n){
       vx[i] <- as.vector(xlst[i])
    }
    
[/code]


CC BY-SA 3.0
2014-12-28T06:32:02.683
2722
2014-12-28T07:21:04.220
2014-12-28T07:21:04.220
728
728
2720
answer


どういったことがしたいのかとか、いろいろ解ってないので自信がありませんが、 まずは、 `i <\- i+1`
は不要です。(そのレベルの質問かな？、と勝手に行間を読んで。。)

`x1` は `x[1]` と表現できない(別物)ので、例えばループの前段で、

[code]

    x <- c(NULL, x1, x2, x3, ..., xn)
    
[/code]

としておいて、xを用意しつつ、`x[1]` に `x1` を、`x[2]` に `x2` を入れていきます。 (今回の質問では、`x[0]`,`x0`
は使わないみたいなのでNULLをいれています。)

つぎに、同じくループの前段で、、

[code]

    vx <- c()
    
[/code]

として、 as.vector(x[i]) を受け入れる変数を用意しておきます。

で、質問にあった

[code]

    i <- 1
    for (i in 1:n)
    {
     vx[i] <- as.vector(x[i])
     // i <- i+1
    }
    
[/code]

を通せば、とりあえず、`vx[1], vx[2], vx[3], ... vx[n]`に値は入ります。

ただ、`vx1, vx2, vx3, ... vxn`には入っていないです。 ~~これをしたいのであれば、ループが終わったあとにでも地道に、

[code]

    vx1 <- vx[1]
    vx2 <- vx[2]
    vx3 <- vx[3]
    ...
    vxn <- vx[n]
    
[/code]

としていくしなないような気がします。（他にあるかも。~~


CC BY-SA 3.0
2014-12-28T07:11:25.313
2727
2014-12-28T08:11:45.610
2014-12-28T08:11:45.610
2992
2992
2720
answer


あくまで質問の字義通りとかんがえると

[code]

    for (i in 1:n) {
        assign(paste('vx', i, sep=''), get(paste('x', i, sep='')))
    }
    
[/code]

で`vx1, vx2, ..., vxn`が生成できます。

  * `assign('A', a)`で変数`A`に`a`を割り当てることが出来ます
  * `get('A')`で変数名を文字列で指定して格納されている値をとることが出来ます。

どちらも動的な処理なので実行パフォーマンスは相当遅いことに留意ください。また、こうしたやり方は要求されている仕様がどうしようもない場合の裏テクみたいなもので、一般的な`R`の流儀ではありません。

代わりに、`R`ではベクトル単位で処理すると効率が良いので、基本としてはそうした方法をお勧めします。


CC BY-SA 3.0
2014-12-28T07:56:23.220
2732
2014-12-28T08:23:01.570
2014-12-28T08:23:01.570
3313
3313
2720
answer


ohgaさんとflied onionさんの回答を参考にしますと、以下の様になるのでしょうか。

[code]

    for (i in 1:n)
    {
       xn <- paste( "x", i, sep="")
      vxn <- paste("vx", i, sep="")
      eval(parse(text=paste(vxn, "<- array(1)")))
      eval(parse(text=paste(vxn, "<- as.vector(", xn, ")")))
    }
    
[/code]


CC BY-SA 3.0
2014-12-28T08:01:11.127
2733
2014-12-28T08:01:11.127
2720
answer


参考までに、[3100さん曰く](https://ja.stackoverflow.com/a/2732/6008)「ベクトル単位で」処理する方法を幾つか述べておきます。

質問のコードからすると、反復可能な配列`x`がありますね。なら、一気に処理してしまいましょう:

[code]

    library(xts)
    data(sample_matrix)
    sample.xts <- as.xts(sample_matrix, descr='my new xts object') # xtsの例から引用
    
    x <- c(sample.xts,sample.xts,sample.xts) # xtsオブジェクトでもベクトルに挿入できる
    vx <- sapply(x, as.vector)
    
[/code]

出力を検査して見ると、データ自体に損害はないようです（が、`xts`の経験がまったくないので自分でご確認を）:

[code]

    > str(x)
    An ‘xts’ object on 2007-01-02/2007-06-30 containing:
      Data: num [1:540, 1:4] 50 50 50 50.2 50.2 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:4] "Open" "High" "Low" "Close"
      Indexed by objects of class: [POSIXct,POSIXt] TZ: 
      xts Attributes:  
    List of 1
     $ descr: chr "my new xts object"
    
    > str(vx)
     num [1:540, 1:4] 50 50 50 50.2 50.2 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:4] "Open" "High" "Low" "Close"
    
[/code]

ただし、`c()`でつないだせいか、`x`を構成する三つの`xts`オブジェクト（そして`vx`の列)が一つになってしまいましたね。回避方法として、オブジェクトの構成を残す`list()`に挿入できます。

[code]

    x <- list(sample.xts,sample.xts,sample.xts)
    vx <- lapply(x, as.vector)
    
[/code]

すると、

[code]

    > str(x)
    List of 3
     $ :An ‘xts’ object on 2007-01-02/2007-06-30 containing:
      Data: num [1:180, 1:4] 50 50.2 50.4 50.4 50.2 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:4] "Open" "High" "Low" "Close"
      Indexed by objects of class: [POSIXct,POSIXt] TZ: 
      xts Attributes:  
    List of 1
      ..$ descr: chr "my new xts object"
     $ :An ‘xts’ object on 2007-01-02/2007-06-30 containing:
      Data: num [1:180, 1:4] 50 50.2 50.4 50.4 50.2 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:4] "Open" "High" "Low" "Close"
      Indexed by objects of class: [POSIXct,POSIXt] TZ: 
      xts Attributes:  
    List of 1
      ..$ descr: chr "my new xts object"
     $ :An ‘xts’ object on 2007-01-02/2007-06-30 containing:
      Data: num [1:180, 1:4] 50 50.2 50.4 50.4 50.2 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:4] "Open" "High" "Low" "Close"
      Indexed by objects of class: [POSIXct,POSIXt] TZ: 
      xts Attributes:  
    List of 1
      ..$ descr: chr "my new xts object"
    
    > str(vx)
    List of 3
     $ : num [1:720] 50 50.2 50.4 50.4 50.2 ...
     $ : num [1:720] 50 50.2 50.4 50.4 50.2 ...
     $ : num [1:720] 50 50.2 50.4 50.4 50.2 ...
    
[/code]

という結果になります。これで三つのベクトルが得られましたが、前よりデータの構築情報が消えています。

妥協策として、`as.vector`の代わりに`as.matrix`を`lapply`でコールすれば良くなりますが、最初の質問からどんどん離れていきますので、ここで終わりにします。ともかく、Rの`apply`系関数は強力なものです。

更なる参考リンク:

  * `apply`ファミリーについて: <http://d.hatena.ne.jp/a_bicky/20120425/1335312593>
  * `mclapply`を用いる簡単な並列化: <http://mkprob.hatenablog.com/entry/2013/11/07/000227>


CC BY-SA 3.0
2015-01-04T03:06:02.397
3012
2015-01-04T03:13:35.047
2017-04-13T12:52:39.113
-1
6008
2720
answer