3

On Twitter I asked the following:

In RStudio, is there an easy way to pipe the last result stored in .Last.value into a function. Say I did:

tbl <- CreateTable(x).

I now want to do View(tbl) but with less typing. Just type

.View

or something. Is that possible? #rstats #rstudio

Is there maybe a general way to do this?

Bob Jansen
  • 1,215
  • 2
  • 12
  • 31
  • You can directly click on the object `tbl` which would get listed under `Environment` tab in Rstudio/ – YOLO Jan 03 '20 at 11:38
  • I want it to be a general function, not just `View()`. For `View()` you can also use [F2](https://twitter.com/jozefhajnala/status/1212757997782536193). – Bob Jansen Jan 03 '20 at 11:39
  • 1
    might be helpful: https://stackoverflow.com/questions/22588816/shorthand-for-last-value-in-r – user63230 Jan 03 '20 at 11:53
  • A Twitter user gave a solution: https://twitter.com/antoine_fabri/status/1213049033553588224 – Bob Jansen Jan 03 '20 at 11:54
  • So .Last.value works, really cool maybe you can reassign with a function to a shorter name or make a shortcut for it – Bruno Jan 03 '20 at 11:56

1 Answers1

4

Here are a few ways, this is all strange stuff so I hope you'll keep it for interactive use, won't put anything in your RProfile and won't share code using those :).

1 - create a binding for .

. will be a shortcut for .Last.Value, saving most of the typing. magrittr pipes and functional sequences will still work, and so will purrr lambdas.

makeActiveBinding(".", function() .Last.value, .GlobalEnv)
4
sqrt(.) # 2

If you have a µ, a λ or another compliant special character easily accessible on your keyboard it might be a good idea to use it instead.

2 - hacking print.function

We can hack print.function so it runs the function on the last value.

Here I couldn't use .Last.value because it's the value of the function itself, so I need to re-execute the previous call, so in some cases it might be slow.

print.function <- function(x){
  tf <- tempfile()
  savehistory(tf)
  last_calls <- parse(text=tail(readLines(tf),2))
  if(as.list(last_calls[[2]])[[1]] == quote(print))
    base:::print.function(x) else print(x(eval.parent(last_calls[[1]])))
}
4
sqrt # 2
4
print(sqrt) # the actual definition

3 - Use package doubt

We can build a dubious operator that will use .Last.value :

# remotes::install_github("moodymudskipper/doubt")
library(doubt)
`?+{fun}` <- function(fun){ fun(.Last.value)}
4
?+sqrt # 2

4 - give a class to the functions you care about

And define a method for an unary operator (+, -, and ! will all work) :

class(sqrt) <- class(summary) <- class(View) <- "magic_function"
`+.magic_function` <- function(fun){ fun(.Last.value)}
4
+sqrt # 2
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167