1

をラップする関数を作成するときに、奇妙な状況に直面していますlm()stats::model.frame()具体的には、関数のモデル出力を に渡すときに関連するエラーが発生しeffectsize::effectsize()ます。

次の例では、 と の 2 つのシナリオがAありBます。では、最初にオブジェクトを作成してから に渡すA関数を定義します。この関数は class のオブジェクトを返します。そのオブジェクトを に渡すと、エラーが発生します。formulamy_formula <- as.formula(paste0(y, "~", x))lm()"lm"effectsize::effectsize()

stats::model.frame(formula = my_formula, data = data_std, drop.unused.levels = TRUE) のエラー: オブジェクト 'my_formula' が見つかりません

不思議なことに、同じオブジェクトを に渡すstats::model.frame()と動作します。

シナリオでは、プリエンプティブ オブジェクトではなく、B内で式を指定する関数を作成します。lm()そのシナリオでは、出力をeffectsize()作品に渡します。

再現可能な例

library(dplyr, warn.conflicts = FALSE)
library(effectsize)

## scenario A -- failing
my_lm_external_formula <- function(.dat, predicted, predictor){
  
  my_formula <- as.formula(paste0(predicted, "~", predictor))
  
  lm(formula = my_formula, data = .dat)
}
## the following line fails
my_lm_external_formula(.dat = mtcars, predicted = "mpg", predictor =  "am") %>% effectsize()
#> Error in stats::model.frame(formula = my_formula, data = data_std, drop.unused.levels = TRUE): object 'my_formula' not found
## although this one works
my_lm_external_formula(.dat = mtcars, predicted = "mpg", predictor =  "am") %>% stats::model.frame()
#>                      mpg am
#> Mazda RX4           21.0  1
#> Mazda RX4 Wag       21.0  1
#> Datsun 710          22.8  1
#> Hornet 4 Drive      21.4  0
#> Hornet Sportabout   18.7  0
#> Valiant             18.1  0
#> Duster 360          14.3  0
#> Merc 240D           24.4  0
#> Merc 230            22.8  0
#> Merc 280            19.2  0
#> Merc 280C           17.8  0
#> Merc 450SE          16.4  0
#> Merc 450SL          17.3  0
#> Merc 450SLC         15.2  0
#> Cadillac Fleetwood  10.4  0
#> Lincoln Continental 10.4  0
#> Chrysler Imperial   14.7  0
#> Fiat 128            32.4  1
#> Honda Civic         30.4  1
#> Toyota Corolla      33.9  1
#> Toyota Corona       21.5  0
#> Dodge Challenger    15.5  0
#> AMC Javelin         15.2  0
#> Camaro Z28          13.3  0
#> Pontiac Firebird    19.2  0
#> Fiat X1-9           27.3  1
#> Porsche 914-2       26.0  1
#> Lotus Europa        30.4  1
#> Ford Pantera L      15.8  1
#> Ferrari Dino        19.7  1
#> Maserati Bora       15.0  1
#> Volvo 142E          21.4  1

####
####
####

# scenario B -- working
my_lm_built_in_formula_via_pipe <- function(.dat, predicted, predictor){
  
  .dat %>%
    select(my_predicted = {{ predicted }}, my_predictor = {{ predictor }}) %>%
    lm(my_predicted ~ my_predictor, data = .)
}
## both calls work:
my_lm_built_in_formula_via_pipe(.dat = mtcars, predicted = "mpg", predictor = "am") %>% effectsize()
#> # Standardization method: refit
#> 
#> Parameter    | Coefficient (std.) |        95% CI
#> -------------------------------------------------
#> (Intercept)  |           2.94e-17 | [-0.29, 0.29]
#> my_predictor |               0.60 | [ 0.30, 0.90]
my_lm_built_in_formula_via_pipe(.dat = mtcars, predicted = "mpg", predictor = "am") %>% stats::model.frame()
#>                     my_predicted my_predictor
#> Mazda RX4                   21.0            1
#> Mazda RX4 Wag               21.0            1
#> Datsun 710                  22.8            1
#> Hornet 4 Drive              21.4            0
#> Hornet Sportabout           18.7            0
#> Valiant                     18.1            0
#> Duster 360                  14.3            0
#> Merc 240D                   24.4            0
#> Merc 230                    22.8            0
#> Merc 280                    19.2            0
#> Merc 280C                   17.8            0
#> Merc 450SE                  16.4            0
#> Merc 450SL                  17.3            0
#> Merc 450SLC                 15.2            0
#> Cadillac Fleetwood          10.4            0
#> Lincoln Continental         10.4            0
#> Chrysler Imperial           14.7            0
#> Fiat 128                    32.4            1
#> Honda Civic                 30.4            1
#> Toyota Corolla              33.9            1
#> Toyota Corona               21.5            0
#> Dodge Challenger            15.5            0
#> AMC Javelin                 15.2            0
#> Camaro Z28                  13.3            0
#> Pontiac Firebird            19.2            0
#> Fiat X1-9                   27.3            1
#> Porsche 914-2               26.0            1
#> Lotus Europa                30.4            1
#> Ford Pantera L              15.8            1
#> Ferrari Dino                19.7            1
#> Maserati Bora               15.0            1
#> Volvo 142E                  21.4            1

reprex パッケージ(v2.0.0)により 2021-08-15 に作成

シナリオ A (B ではなく) でエラーが発生する理由と、エラーが発生しないのになぜeffectsize()失敗するのstats::model.frame()ですか?

4

2 に答える 2

2

lmlm オブジェクトの および メソッドのスコープの問題に遭遇することがよくあります。この言語でのコンピューティングに関しては良い経験を積んでいますが、決して問題に遭遇しないとは保証できません。呼び出しと同じ環境で作成されていない lm オブジェクトでは機能しないメソッドがいくつかあります。一部の悪いメソッドでは、グローバル環境で作成する必要さえあります。

my_lm_external_formula <- function(.dat, predicted, predictor){
  
  predicted <- as.name(predicted)
  predictor <- as.name(predictor)
  
  eval(bquote(lm(formula = .(predicted) ~ .(predictor), data = .dat)))
}  

effectsize(
  my_lm_external_formula(.dat = mtcars, 
                         predicted = "mpg", 
                         predictor =  "am")
)
#works
于 2021-08-18T12:09:12.890 に答える