全ての組み

合わせを持つリストを生成
去年のデータ解析にて、Cpプロットを出すのに全ての組み合わせを出すという作業があった。手でやってる人が大半であったが、手でやったら負けですよね。というわけで去年はPerlを使ってRのコードを吐き出させていたわけですが、Rの中で完結したかった。で、Rで関数書き直そうかと思ったんだけど、うまくできないというへたれさ*1

で、expand.grid使えばどうにかできる気がしたのでやってみたお。gridには0、1が入った行列みたいな感じのやつ。

car <- c("height","weight","length","eu")
grid <- expand.grid(height = c(0,1), weight = c(0,1), length = c(0,1),eu = c(0,1))

reg <- c()

for(i in 2:length(grid[,1])){
  reg[i-1] <- list(car[grid[i,]==1])
}

全ての組み合わせが入ったリストができる。あとはこれをevalとかしてやればどうにかできるな。

> reg
[[1]]
[1] "height"

[[2]]
[1] "weight"

[[3]]
[1] "height" "weight"

[[4]]
[1] "length"

[[5]]
[1] "height" "length"

[[6]]
[1] "weight" "length"

[[7]]
[1] "height" "weight" "length"

[[8]]
[1] "eu"

[[9]]
[1] "height" "eu"

[[10]]
[1] "weight" "eu"

[[11]]
[1] "height" "weight" "eu"

[[12]]
[1] "length" "eu"

[[13]]
[1] "height" "length" "eu"

[[14]]
[1] "weight" "length" "eu"

[[15]]
[1] "height" "weight" "length" "eu"

evalでどうやればいいかも一応少し書いておくか、念のため。とりあえずデータをでっちあげる。

height <- 1:10+rnorm(10)*0.3
weight <- 11:20+rnorm(10)*2
length <- 1:10+rnorm(10)*10
eu <- rep(0:1, c(5,5))
price <- runif(10)

reg_string <- paste("lm(price ~",reg_string,")",sep="")

で、evalしてやれば

> eval(parse(text=reg_string))

Call:
lm(formula = price ~ height + weight + length + eu)

Coefficients:
(Intercept)       height       weight       length           eu
   -0.52711      0.03427      0.04664      0.01802     -0.31849

こんな感じでできる。これで大量にモデルを生成して、コーヒーでも飲みながらどのモデルが最適かを吟味すればおk*2

ちなみに15個くらいの線形回帰モデルを一気に生成するのはこんなの。sarimaの時も同じようなことしたけど、計算時間が全然違って泣くwww。

for(i in 1:length(reg)){
  for(j in 1:length(reg[[i]])){
    reg_string <- ""
    if(j ==1){
      reg_string <- paste(reg_string,reg[[i]][j],sep="")
    }else{
      reg_string <- paste(reg_string," + ",reg[[i]][j],sep="")
    }
    reg_string <- paste("summary(lm(price ~",reg_string,"))",sep="")
    print(eval(parse(text=reg_string)))
  }
}

*1:まあ、再帰をうまく書けないからGaucheとか勉強してるわけですが

*2:しかし、現実はそう甘くないw