Hello,
Can't you use eval()?
This
return eval(expr)
instead of
return expr.evaluate()
Best regards,
João Matos
On 23/02/2020 23:04, Brendan Barnwell wrote:
On 2020-02-23 14:38, Steven D'Aprano wrote:
Hi Aaron, and welcome!
Your proposal would be a lot more interesting to me if I knew what this
binary ~ would actually do, without having to go learn R or LaTeX.
You say:
I think it would be awesome to have in the language, as it would allow
modelling along the lines of R that we currently only get with text,
e.g.:
smf.ols(formula='Lottery ~ Literacy + Wealth + Region', data=df)
With a binary context for ~, we could write the above string as pure
Python
I'm confused. Why can't you just write
'Lottery ~ Literacy + Wealth + Region'
as a literal string? That's an exact copy and paste from your example,
and it works for me.
I'm not the OP but. . .
In R there is a tilde operator that is used to indicate "depends
on" when separating the dependent and independent variables in a
statistical model formulation. The example given is how it has to be
done in Python. In R you just write `Lottery ~ Literacy + Wealth +
Region` (i.e., as code with no quotes).
That said, the way this works in R depends on additional
"features" of R whose absence in Python make it a heavier lift than
just adding a tilde. R can magically defer evaluation of names so
that you can write something like that tilde expression and pass an
additional argument specifying the table whose columns are the given
variables (i.e., a table with columns for Lottery, Literacy, etc.),
and then it will later evaluate the names by looking them up as
columns. This won't work in Python because even if you had the tilde,
you couldn't do this:
ols(Lottery ~ Literacy + Wealth + Region, data=df)
Because that model expression is a function argument, Python
semantics require it to be evaluated before the call is made, so you
can't defer evaluation and later use the names as column names to look
up in the provided table.
In order to make it work you'd need something else that I've
sometimes wished for, which is a smooth way to create and pass around
unevaluated expressions, and then later trigger their evaluation in
the context of a given namespace (such as the one where the evaluation
is triggered). Right now the only approximation to this is lambda, but
lambda closes over variables based on the lexical context where it's
defined, not where it's called, so it doesn't really work. In other
words, what I'd like is the ability to do something like this:
def foo():
expr = deferred(a + b + c)
bar(expr)
def bar(x):
a, b, c = 1, 2, 3
# this should return 6
return expr.evaluate()
If such functionality existed, then a tilde operator could indeed
be used to create model definitions using deferred evaluations like in R.
However, I think deferred evaluation is the more important
functionality here. If we had deferred evaluation without the tilde,
we could still do what R does by using a different operator instead of
tilde, at worst perhaps having to parenthesize the dependent-variable
expression (in case our alternative "depends" operator had the wrong
precedence). But without deferred evaluation, the tilde operator
gains little, at least in terms of providing model-evaluation
expressions like those in R.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/python-ideas@python.org/message/UFTA3RK7O27VZM3XJZJJJMCUDVQSEFXI/
Code of Conduct: http://python.org/psf/codeofconduct/