まずは蝋の翼から。

学んだことを書きながら確認・整理するためのメモブログ。こういうことなのかな?といったことをふわっと書いたりしていますが、理解が浅いゆえに的はずれなことも多々あると思うのでツッコミ歓迎

文字列からformulaを作りたい

やりたいこと

リストにある文字を組み合わせて作った式をfor文で動的に変えていきたい。

問題点

以下のコードのように、felm関数のformulaに文字列で式を渡した場合エラー。

ちなみに、lfe::felmは固定効果モデルを使うときの関数。

knknkn.hatenablog.com

library(tidyverse)
library(lfe)

d = as_tibble(iris)

sepal_vars = c('Sepal.Length', 'Sepal.Width')
petal_vars = c('Petal.Length', 'Petal.Width')

for (sepal_var in sepal_vars) {
  for (petal_var in petal_vars) {
    f = paste0(sepal_var,' ~ ', petal_var)  # 例) Sepal.Length ~ Petal.Length
    d %>% 
      felm(formula = f, data = .) # 例) felm(formula = Sepal.Length ~ Petal.Length, data = .) %>% 
      print()
  }
}


# => new.env(parent = formenv) でエラー:  NULL環境の使用は廃要素です 

解決策

as.formulaを使う。

Rのオブジェクトのひとつとして、式を表現するformulaクラスというのがあり、formulaにはformulaクラスを渡す必要がある。
そのためには、as.formula関数で文字列クラスをformulaクラスに変換して渡す必要がある模様。

修正コード

library(tidyverse)
library(lfe)

d = as_tibble(iris)

sepal_vars = c('Sepal.Length', 'Sepal.Width')
petal_vars = c('Petal.Length', 'Petal.Width')

for (sepal_var in sepal_vars) {
  for (petal_var in petal_vars) {
    f = as.formula(paste0(sepal_var,' ~ ', petal_var))
    d %>% 
      felm(formula = f, data = .) %>% 
      print()
  }
}

余談

lfe::felmでは前述のように動かないが、stats::lmだと文字列で渡しても動く(そのため、今回はlfe::felmで例示していた)。

library(tidyverse)
d = as_tibble(iris)

sepal_vars = c('Sepal.Length', 'Sepal.Width')
petal_vars = c('Petal.Length', 'Petal.Width')

for (sepal_var in sepal_vars) {
  for (petal_var in petal_vars) {
    f = paste0(sepal_var,' ~ ', petal_var)
    d %>% 
      lm(formula = f, data = .) %>% 
      print()
  }
}

マニュアル見ると、

an object of class "formula" (or one that can be coerced to that class) とあるのでstats::lmではformulaクラスに強制変換されている模様。

・・・と思ったら、lfe::felmでも同様の記載あるな。謎。

参考

m884.hateblo.jp

ill-identified.hatenablog.com