简体   繁体   中英

Using ipython magics in R jupyter notebook?

I installed jupyter with conda install jupyter and am running a notebook with the r kernal installed from conda create -n my-r-env -cr r-essentials

I am running a notebook and want to run a bash command from a shell.

!echo "hi"
Error in parse(text = x, srcfile = src): <text>:1:7: unexpected string constant
1: !echo "hi"

For comparison, in an notebook with a python kernel:

!echo "hi"
hi

Is there a way to set up R notebooks to have the same functionality as the ipython notebook with regards to bash commands (and maybe other magics)?

For just bash commands, it's possible to get system commands to work. For example, in the IRkernel:

system("echo 'hi'", intern=TRUE)

Output:

'hi'

Or to see the first 5 lines of a file:

system("head -5 data/train.csv", intern=TRUE)

As IPython magics are available in the IPython kernel (but not in the IRkernel), I did a quick check if it was possible to access these using the rPython and PythonInR libraries. However, the issue is that get_ipython() isn't visible to the Python code, so none of the following worked:

library("rPython")
rPython::python.exec("from IPython import get_ipython; get_ipython().run_cell_magic('writefile', 'test.txt', 'This is a test')")

library("PythonInR")
PythonInR::pyExec("from IPython import get_ipython; get_ipython().run_cell_magic('head -5 data/test.csv')")

A cosmetic improvement to the output of system can be obtained by wrapping the call in cat and specify '\\n' as the separator, which displays the output on separate lines instead of separated by whitespaces which is the default for character vectors. This is very useful for commands like tree , since the format of the output makes little sense unless separated by newlines.

Compare the following for a sample directory named test :

Bash

$ tree test
test
├── A1.tif
├── A2.tif
├── A3.tif
├── README
└── src
    ├── sample.R
    └── sample2.R

1 directory, 6 files

R in Jupyter Notebook

system only, difficult to comprehend output:

> system('tree test', intern=TRUE)

'test' '├── A1.tif' '├── A2.tif' '├── A3.tif' '├── README' '└── src' '    ├── sample.R' '    └── sample2.R' '' '1 directory, 6 files

cat + system , output looks like in bash:

> cat(system('tree test', intern=TRUE), sep='\n')

test
├── A1.tif
├── A2.tif
├── A3.tif
├── README
└── src
    ├── sample.R
    └── sample2.R

1 directory, 6 files

Note that for commands like ls , the above would introduce a newline where outputs are normally separated by a space in bash.

You can create a function to save you some typing:

> # "jupyter shell" function
> js <- function(shell_command){
>     cat(system(shell_command, intern=TRUE), sep='\n')
> }
>
> # brief syntax for shell commands
> js('tree test')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM