17472


Rでいろいろな次数についてモデルのAICを計算させ

[code]

    for(p in 1:k){
      for(q in 1:k){
    :  
      aic <- infocriteria(fit)
      answer<-cbind(p,q,r,aic)
      print(answer)
    }}
    
[/code]

のように出力させているのですが、次数が高く最初に計算したものがコンソールから消えてしまいます。自動化させたいので変数を設定して格納させようとか考えているのですがどのような方法が考えられますでしょうか？

また、出力結果ですが、

[code]

                 p q r s         
    Akaike       1 1 1 1 4.07
    Bayes        1 1 1 1 4.08
    Shibata      1 1 1 1 4.08
    Hannan-Quinn 1 1 1 1 4.08
                 p q r s         
    Akaike       1 1 1 2 4.08
    Bayes        1 1 1 2 4.08
    Shibata      1 1 1 2 4.07
    Hannan-Quinn 1 1 1 2 4.08
    :
    
[/code]

のようにp q r sの部分が繰り返し出てくるのが邪魔なのですがどのように対処すればよろしいでしょうか。今流行り？のdplyrなどを使えばよいでしょうか？

**（追記）**  
計算させてリストの中身を表示させようと

> print(lst)

としたら

[code]

    [[1]]
    [[1]][[1]]
    [[1]][[1]][[1]]
    [[1]][[1]][[1]][[1]]
    
    Akaike       1 1 1 1 4.107875
    Bayes        1 1 1 1 4.111026
    Shibata      1 1 1 1 4.107875
    Hannan-Quinn 1 1 1 1 4.108906
    
    [[1]][[1]][[1]][[2]]
    
    Akaike       1 1 1 2 4.100747
    Bayes        1 1 1 2 4.104686
    Shibata      1 1 1 2 4.100747
    Hannan-Quinn 1 1 1 2 4.102036
    
    
    [[1]][[1]][[2]]
    [[1]][[1]][[2]][[1]]
    
    Akaike       1 1 2 1 4.103414
    Bayes        1 1 2 1 4.106959
    Shibata      1 1 2 1 4.103414
    Hannan-Quinn 1 1 2 1 4.104574
    
    [[1]][[1]][[2]][[2]]
    
    Akaike       1 1 2 2 4.095238
    Bayes        1 1 2 2 4.099571
    Shibata      1 1 2 2 4.095238
    Hannan-Quinn 1 1 2 2 4.096656
    
[/code]

のようになりました。リストの中を見てcsvなどに出力し直すにはどうしたらよいでしょうか？

[code]

    write.csv
    
[/code]

でしょうか？

**（再追記）**  
dplyrの方式ですと

[code]

    f <- function(p,q,r,s) {  
    hogehoge
    
    print(aic.sg)
    }
    params <- expand.grid(p = 1:1, q = 1:1, r = 1:3, s = 1:2)
    
    params %>% 
      rowwise %>%
      mutate(aic = f(p, q, r, s))
    
[/code]

のように記述し、

[code]

    Error: incompatible size (4), expecting 1 (the group size) or 1
    
[/code]

のエラーが返ってきます。  
functionの返り値が

[code]

    Akaike       4.108074
    Bayes        4.112013
    Shibata      4.108074
    Hannan-Quinn 4.109363
    
[/code]

のように4行に渡っていることがimcompatibleと言われてしまう原因なのでしょうか？


CC BY-SA 3.0
2015-10-09T06:24:59.113
17468
2017-06-20T16:09:25.823
2017-06-20T16:09:25.823
12457
12457
question
r dplyr
Rで生成したデータの前処理


リストを使うのはいかがでしょうか。

[code]

    lst <- list()
    for(p in 1:k){
      plist <- list()
      for(q in 1:k) {
        qlist <- list()
        for(r in 1:k) {
          rlist <- list()
          for(s in 1:k) {
            aic <- infocriteria(fit)
            rlist[[s]] <- cbind(p, q, r, s, aic, deparse.level = 0)
          }
          qlist[[r]] <- rlist
        }
        plist[[q]] <- qlist
      }
      lst[[p]] <- plist
    }
    
[/code]

リスト `lst` に結果が格納されて、`p, q, r, s` がリストの suffix になります。また、

> p q r sの部分が繰り返し出てくるのが邪魔なのですが、

これは列ラベルですので、`cbind` で `deparse.level = 0` を設定することで非表示にできます。

CSV 形式でファイルに保存するには、まず `lst` を平坦化(flatten)します。それから `write.table`
でデータをファイルに保存します。

[code]

    flatList <- unlist(unlist(unlist(lst, recursive=F), recursive=F), recursive=F)
    output <- file("output.csv", open="w")    
    truncate(output)
    for(i in 1:length(flatList)){
      write.table(flatList[[i]], file=output, append=T, sep=",", col.names=F)
    }
    close(output)
    
[/code]

**追記**

4重ループになると可読性が悪くなりますね… 効率的な書き方を思い付いたらまた更新します。

**追記その2**

別の方法を思い付きました。

まず、予め全ての `p, q, r, s` の組み合わせを作ってしまいます。

[code]

    # p = 1, q = 1, r = 1:2, s = 1:4 の場合(1:1 は 1 でも可)
    comb <- expand.grid(1:1, 1:1, 1:2, 1:4)
    comb <- comb[order(comb[,1], comb[,2], comb[,3], comb[,4]),]
    lst <- list()
    for (i in 1:nrow(comb)) {
      p = comb[i,1]; q = comb[i,2]; r = comb[i,3]; s = comb[i,4]
               :
      aic <- infocriteria(fit)
      lst[[i]] <- cbind(p, q, r, s, aic, deparse.level = 0)
    }
    
[/code]

計算結果を CSV 形式でファイルに保存する場合は以下の様にします。

[code]

    output <- file("output.csv", open="w")    
    truncate(output)
    for(i in 1:length(lst)){
      write.table(lst[[i]], file=output, append=T, sep=",", col.names=F)
    }
    close(output)
    
[/code]

出力先は `output.csv` としています(適宜変更して下さい)。`write.table` を使っているのは、`write.csv`
ですと追記(append)ができないためです。

※ データを見る場合は `print` ではなく、

[code]

    page(lst, m="p")
    
[/code]

とすると `more` や `less` コマンドと同じ操作性で扱えますので便利ですよ。


CC BY-SA 3.0
2015-10-09T07:33:19.327
17472
2015-10-10T09:31:30.587
2015-10-10T09:31:30.587
17468
answer


これは必要以上にネストを深くしすぎていると思います。

詳しくないのですが、`p,q,r,s`を引数に取ってモデルのAICを返す関数をつくって、それに次数の組を渡すようなやり方ではだめなのでしょうか？
`expand.grid()`で変数の組み合わせをつくれます。わかりやすく`for`文で書くならこんな感じです。

[code]

    f <- function(p,q,r,s) {
      ...略...
      fit <- lm(...)
      infocriteria(fit)
    }
    
    params <- expand.grid(p = 1:k_p, q = 1:k_q, r = 1:k_r, s = 1:k_s)
    
    result <- list()
    for (i in 1:nrow(params)) {
      param <- params[i,]
      param$aic <- f(param$p, param$q, param$r, param$s)
    
      result[[i]] <- param
    }
    
    do.call(rbind, result)
    
[/code]

`lapply`を使うなら、おそらくこんな感じです。

[code]

    do.call(rbind,
            lapply(1:nrow(params), function(i) {
              param <- params[i,]
              param$aic <- f(param$p, param$q, param$r, param$s)
              param
            }))
    
[/code]

dplyrならたぶんこれだけで済むはずです。

[code]

    params %>%
      mutate(aic = f(p, q, r, s))
    
[/code]


CC BY-SA 3.0
2015-10-21T15:55:10.657
17912
2015-10-21T15:55:10.657
2544
17468
answer


> (再追記）  
>  dplyrの方式ですと  
>  :  
>  のように4行に渡っていることがimcompatibleと言われてしまう原因なのでしょうか？

まず、`f` function の最後の `print(aic.sg)` を `aic.sg` に変更します(`print(aic.sg)`
のままでも構わないのですが、画面表示の必要はないと思われますので)。

[code]

    f <- function(p,q,r,s) {  
      hogehoge
         :
      aic.sg
    }
    
[/code]

dplyr は使った事がないのでどうも勝手が良く分からないのですが、以下の様にするのではないでしょうか。

[code]

    > dd <- params %>%
        rowwise %>%
          do({
            v <- f(p, q, r, s)
            data.frame(name=rownames(v), ., v)
          }) %>% print()
    
    Source: local data frame [24 x 6]
    Groups: <by row>
    
               name     p     q     r     s       V1
             (fctr) (int) (int) (int) (int)    (dbl)
    1        Akaike     1     1     1     1 1.124508
    2         Bayes     1     1     1     1 1.141493
    3       Shibata     1     1     1     1 1.124490
    4  Hannan-Quinn     1     1     1     1 1.130749
    5        Akaike     1     1     2     1 1.124508
    6         Bayes     1     1     2     1 1.141493
    7       Shibata     1     1     2     1 1.124490
    8  Hannan-Quinn     1     1     2     1 1.130749
                                :
    
[/code]

※ V1 の値は適当です

なお、CSV 形式でのファイル出力は以下の様になります。

[code]

    > write.table(dd, file="output.csv", sep=",", row.names=F, col.names=F)
    
[/code]


CC BY-SA 3.0
2015-10-29T16:55:46.770
18217
2015-10-29T17:33:38.083
2015-10-29T17:33:38.083
17468
answer