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.

--
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail."
   --author unknown
_______________________________________________
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/FU5P4Q7EQV6VOE7DFSISMSEFW3JD6OEZ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to