R — Использование patsy.dmatrices() с ретикуляцией

У меня проблема с пространством имен при попытке использовать функцию patsy.dmatrices() с пакетом reticulate R.

Вот простой воспроизводимый пример:

patsy <- import("patsy")
# Data
dataset <- data.frame(Y=rnorm(1000,2.5,1))
# Null model
formula_null <- "I(Y-1) ~ 1"
dmat = patsy$dmatrices(formula_null, data=dataset, NA_action="drop",
                                         return_type="dataframe")

Я получаю следующую ошибку:

Error in py_call_impl(callable, dots$args, dots$keywords) : 
AttributeError: 'NoneType' object has no attribute 'f_locals'

Я думаю, что это связано с пространством имен (см. внутри функции), что можно исправить с помощью аргумента eval_env функции dmatrices(), но я не смог понять, как это сделать.

Это довольно проблематично, когда мы хотим использовать в R пакет Python statsmodels, который использует пакет patsy для формул.

Спасибо за вашу помощь,


person Ghislain Vieilledent    schedule 25.06.2018    source источник


Ответы (1)


Я не уверен, но я думаю, что ваше предположение о пространствах имен верно, и это неудачное взаимодействие между patsy и reticulate. По умолчанию patsy пытается заглянуть в область действия вызывающего объекта, чтобы оценить любые нераспознанные функции/переменные в формуле (точно так же, как это делают функции формулы R). Это требует использования самоанализа стека Python, чтобы заглянуть в область действия вызывающего объекта. Но поскольку вызывающий абонент говорит на совершенно другом языке, это почти наверняка не сработает.

Можно переопределить обычное поведение patsy при чтении пространства имен вызывающей стороны, используя аргумент eval_env для dmatrices. (документы.) Попробуйте следующее:

dmat = patsy$dmatrices(formula_null, data=dataset, NA_action="drop",
                       return_type="dataframe",
                       # New:
                       eval_env=patsy$EvalEnvironment(c())
                       )

Идея состоит в том, что здесь мы создаем пустой объект EvalEnvironment и говорим patsy использовать его вместо того, чтобы пытаться прочитать окружение вызывающего объекта.

Я не знаком с reticulate, поэтому вам может понадобиться настроить вышеприведенное, чтобы оно работало — в Python это будет эквивалентно:

dmat = patsy.dmatrices(formula_null, data=dataset, NA_action="drop",
                       return_type="dataframe",
                       eval_env=patsy.EvalEnvironment([])

В частности, если reticulate не преобразует c() в пустой список, вам нужно найти что-то, что это делает. (Может попробовать patsy$EvalEnvironment(list())?)

person Nathaniel J. Smith    schedule 26.06.2018
comment
Спасибо, это было полное спасение жизни! - person noctilux; 17.02.2021