Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pipe in magrittr package is not working for function load()

Tags:

r

magrittr

It seem %>% in the magrittr package is not working for the function load(). This is my minimal example to reproduce my question.

## Create two example variables and save to tempdir()
a <- 1
b <- 1

save(list = ls(), file = file.path(tempdir(), 'tmp.RData'))

## Remove all variables and load into global environment
# rm(list = ls())

load(file.path(tempdir(), 'tmp.RData'))
ls()
# [1] "a" "b"

# Write the same code with pipe "%>%", but not variable is loaded
# rm(list =ls())
library(magrittr)

tempdir() %>% file.path('tmp.RData') %>% load
ls()
# character(0)

I don't understand why the pipe is not working for load(). Thanks for any suggestions.

like image 820
Bangyou Avatar asked Nov 21 '14 04:11

Bangyou


1 Answers

The envir argument in load() needs to be specified as either globalenv() or parent.frame(3).

# in a fresh R session ...
a <- 1
b <- 1
save(list = ls(), file = file.path(tempdir(), 'tmp.RData'))

# in another fresh session ...
ls()
# character(0)
tempdir() %>% file.path("tmp.RData") %>% load(envir = globalenv())
ls()
# [1] "a" "b"

The following also works:

tempdir() %>% file.path("tmp.RData") %>% load(envir = parent.frame(3))

I'll try to explain why. When you call load() from any environment, the function loads the new objects in the parent environment.

Now, the global environment globalenv() is your R workspace. So, if you call load from the global environment (i.e. the workspace) everything works as you expect. Visualise this:

  • Global environment
    • load()

However, if you call load() from inside a function, then you've inserted an environment in between load and the global environment. Visualise this:

  • Global environment
    • function
      • load()

This is exactly what happens when you put %>% into the mix:

  • Global environment
    • %>%
      • load()

There are two solutions for resolving this. Either explicitly point to globalenv() or walk 3 steps up the chain to the global environment using parent.frame(3).


Note: There was an issue reported on GitHub for this. Not sure what the resolution was, or if there is one yet. The issue was just reported in September.

Many thanks to @Andrie for improving this explanation.

like image 193
Rich Scriven Avatar answered Jan 04 '23 14:01

Rich Scriven