rpipearithmetic-expressions

Chain arithmetic operators with the R |> pipe


This is basically the same question as Chain arithmetic operators in dplyr with %>% pipe but updated for the new (as R 4.1) pipe operator |>.

How can I chain arithmetic operators with the R native pipe |>? With dplyr/magrittr, you can use backticks for arithmetic operators, but that doesn't work with the inbuilt R pipe operator. Here's a simple example:

R.version$version.string
# [1] "R version 4.2.2 (2022-10-31 ucrt)"

x <- 2
# With dplyr/magrittr, you can use backticks for arithmetic operators
x %>% `+`(2)
# [1] 4

# But that doesn't work with the inbuilt R pipe operator
x |> `+`(2)
#  Error: function '+' not supported in RHS call of a pipe

Hopefully, the answer would be generic enough to work for any operator or in-built function that does not usually work nicely with the native R pipe (my version is R 4.2.2).

The answer https://stackoverflow.com/a/72086492/2449926 has lots of useful information on the differences between %>% and |>, but none that quite answers my question.


Solution

  • There are two more possibilites, that are already mentioned in https://stackoverflow.com/a/72086492/12505251 :

    1. Use brackets:
    2 |> (`+`)(3)
    #> [1] 5
    
    1. Use the placeholder _ and a named argument of the binary operator:
    2 |> `+`(lhs = _, 3)
    #> [1] 5
    

    Note: In the cases of + or %*% it does not seem to matter how exactly the argument is named. I guess this can be generalized to all binary operators (using R version 4.2.1).

    2 |> `+`(foo = _, 3)
    #> [1] 5
    2 |> `+`(bar = _, 3)
    #> [1] 5
    2 |> `+`(lhs = _, 3)
    #> [1] 5
    2 |> `+`(rhs = _, 3)
    #> [1] 5
    
    c(1, 3) %*% t(c(1, 4))
    c(1, 3) |> `%*%`(foo = _, t(c(1, 4)))
    c(1, 3) |> `%*%`(bar = _, t(c(1, 4)))
    c(1, 3) |> (`%*%`)(t(c(1, 4)))
    # they all return
    #>      [,1] [,2]
    #> [1,]    1    4
    #> [2,]    3   12
    

    Of course, these two variants are not identical:

    c(1, 3) |> `%*%`(foo = _, t(c(1, 4)))
    #>      [,1] [,2]
    #> [1,]    1    4
    #> [2,]    3   12
    
    c(1, 3) |> `%*%`(t(c(1, 4)), foo = _)
    #>      [,1]
    #> [1,]   13