Rのformula をdata.frame の色々な変数の組み合わせで内容を変えながらやりたいのだが

というような質問を受けた。

glm関数とかでみかける、
A ~ B + C
みたいな式の、A,B,Cをfor loopとかで内容変えながら生成する方法はないかとおもって。
A,B,Cはデータの列名やけど、その名前を変数に格納して渡しても無理でさ。
いちいちもとのデータの列名そのものをA,B,Cとかに変えてやるっていうのも思いついたけど、正攻法とは思えず。

いやおそらくその方法のほうが正攻法っぽいと思われる。

やりたいことを素直に表現するなら、評価式はA ~ B + C と書くのを規則に従ってたくさん文字列として生成して、その文字列をeval 関数に渡すのだが文字列なのでparse 関数で渡してゴリ押ししよう。

# 適当なサンプルデータのdataframe
cols <- head(colnames(iris), -1)

# A ~ B + C のBCの組み合わせ
cmb <- combn(length(cols)-1, 2)

# 4番目のPetal.Width を Petal.Width ~ B + C と推定する
# 普通に全部素直に書いたら
glm(Petal.Width ~ Sepal.Length + Sepal.Width, data=iris)
glm(Petal.Width ~ Sepal.Length + Petal.Length, data=iris)
glm(Petal.Width ~ Sepal.Width + Petal.Length, data=iris)

# 上記式を文字列的に書いて
# 強引に評価式としてRに計算させる

for(i in 1:ncol(cmb)){ # すべてのパターンの数
  # 評価したい式を文字列で生成する
  equation <- sprintf("glm(Petal.Width ~ %s + %s, data=iris)", cols[cmb[1,i]], cols[cmb[2,i]])
  # 文字列をRで計算させる
  print(eval(parse(text=equation)))
}
Call:  glm(formula = Petal.Width ~ Sepal.Length + Sepal.Width, data = iris)

Coefficients:
 (Intercept)  Sepal.Length   Sepal.Width  
     -1.5635        0.7233       -0.4787  

Degrees of Freedom: 149 Total (i.e. Null);  147 Residual
Null Deviance:	    86.57 
Residual Deviance: 22.25 	AIC: 147.5

Call:  glm(formula = Petal.Width ~ Sepal.Length + Petal.Length, data = iris)

Coefficients:
 (Intercept)  Sepal.Length  Petal.Length  
   -0.008996     -0.082218      0.449376  

Degrees of Freedom: 149 Total (i.e. Null);  147 Residual
Null Deviance:	    86.57 
Residual Deviance: 6.144 	AIC: -45.58

Call:  glm(formula = Petal.Width ~ Sepal.Width + Petal.Length, data = iris)

Coefficients:
 (Intercept)   Sepal.Width  Petal.Length  
     -0.7065        0.0994        0.4263  

Degrees of Freedom: 149 Total (i.e. Null);  147 Residual
Null Deviance:	    86.57 
Residual Deviance: 6.082 	AIC: -47.12