tidyverse / magrittr

Improve the readability of R code with the pipe
https://magrittr.tidyverse.org
Other
957 stars 157 forks source link

Feature request: Assignment expression operator #248

Closed kepler471 closed 3 years ago

kepler471 commented 3 years ago

Hello ✌️

I have found myself wanting to use an operator that can assign a value to a variable, and also return that variable. This has been added to Python in version 3.8, and is describe in PEP 572. That may be a good place to better understand the operator and some of its use cases.

Would this be something that could fit within the magrittr package?

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

simple_assignment %<:% 3
#> [1] 3

simple_assignment
#> [1] 3

use_with_pipes %<:% 
  tibble(xx = c(1,2,3,4,5),
       yy = c(55,66,77,88,99)) %>% 
  mutate(zz = xx * yy)
#> # A tibble: 5 × 3
#>      xx    yy    zz
#>   <dbl> <dbl> <dbl>
#> 1     1    55    55
#> 2     2    66   132
#> 3     3    77   231
#> 4     4    88   352
#> 5     5    99   495

# Edit: This example with pipes shows that it doesn't work as I
# would want. It does not evaluate the full rhs. A rightward 
# version of this operator does work, but would want both to
# work the same way.
use_with_pipes
#> # A tibble: 5 × 2
#>      xx    yy
#>   <dbl> <dbl>
#> 1     1    55
#> 2     2    66
#> 3     3    77
#> 4     4    88
#> 5     5    99

if (inline_cond %<:% 42 == 42) "yay" else ":("
#> [1] "yay"

inline_cond
#> [1] 42

Created on 2021-08-09 by the reprex package (v2.0.1)

lionel- commented 3 years ago

<- already returns the RHS invisibly. You need parentheses in order to trigger a print, or to work around operator precedence as in your if example.

if ((cond <- 42) == 42) "yay"