Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Same function but using for it the name %>% causes a different result compared when using the name :=

I am using a function from @Konrad Rudolph but changed its name from %>% to := and get for the same call different results.

`%>%` = function (lhs, rhs) {
  subst = call('substitute', substitute(rhs), list(. = lhs))
  eval.parent(eval(subst))
}

`:=` <- `%>%`

1 %>% .+2 %>% .*3
#[1] 7

1 := .+2 := .*3
#[1] 3

Or with a different function.

`%>%` <- function(lhs, rhs) {
  assign(".", lhs, envir=parent.frame())
  eval(substitute(rhs), parent.frame())
}

`:=` <- `%>%`

1 %>% .+2 %>% .*3
#[1] 7

1 := .+2 := .*3
#[1] 9

Why do I get other results when using the function named :=?

like image 669
GKi Avatar asked Sep 16 '25 22:09

GKi


1 Answers

The reason is operator precedence. We can use the lobstr package to see the abstract syntax tree for the code.

lobstr::ast(1 %>% .+1 %>% .+2)
█─`+` 
├─█─`+` 
│ ├─█─`%>%` 
│ │ ├─1 
│ │ └─. 
│ └─█─`%>%` 
│   ├─1 
│   └─. 
└─2 

vs

lobstr::ast(1 := .+1 := .+2)
█─`:=` 
├─1 
└─█─`:=` 
  ├─█─`+` 
  │ ├─. 
  │ └─1 
  └─█─`+` 
    ├─. 
    └─2 

So when you run the %>% version, the pipes are happening before the additions, but with the := version, the addition happens before the :=

If you add in the implicit parenthesis, you'll see that these two are equivalent

1 %>% .+1 %>% .+2
((1 %>% .)+(1 %>% .))+2

however the behavior you might expect would need to look like

1 %>% (.+1) %>% (.+2)

but still "works". And this is how the other expression breaks down

1 := .+1 := .+2
1 := ((.+1) := (.+2))
(1+1) := (1+2)

The way the function was defined, the middle term essentially disappears since the . is replaced by the outer := so there are no free . variables left for the inner =

The order of operations is defined on the ?Syntax help page. You cannot change the precedence for functions without changing the R source code itself. While not listed explicitly on the page, := has the same precedence as <- (it's aliased as a LEFT_ASSIGN in the parser).

like image 170
MrFlick Avatar answered Sep 18 '25 17:09

MrFlick