Jupyter可以在Python笔记本中运行单独的R笔记本吗?

时间:2017-11-01 02:35:44

标签: r ipython jupyter-notebook ipython-notebook jupyter-irkernel

我有一个Jupyter笔记本(python3)这是一个批处理作业 - 它使用%run运行三个单独的python3笔记本。我想从我的批处理中调用第四个Jupyter R-kernel笔记本。

有没有办法在Jupyter / iPython中从Python笔记本执行外部R笔记本?

当前设置:

run_all.ipynb :( python3内核)

%run '1_py3.ipynb'
%run '2_py3.ipynb'
%run '3_py3.ipynb'
%run '4_R.ipynb'

三个python3笔记本正确运行。 R笔记本在Jupyter中单独打开时运行正常 - 但是当使用%run中的run_all.ipynb调用时,它会失败。它被解释为python,并且单元格在第一行给出了python错误:

cacheDir <- "caches"
     

TypeError:一元的坏操作数类型 - :'str'

我对从python笔记本运行单独的R笔记本的任何解决方案感兴趣 - Jupyter magic,shell,python库等等。我也对一个解决方法感兴趣 - 例如一个方法(比如shell脚本)可以运行所有四个笔记本(python3和R),即使这不能在python3笔记本中完成。

(注意:我已经了解如何在单元格中嵌入%%R。这不是我想要做的。我想调用一个完整的单独的R笔记本。)

2 个答案:

答案 0 :(得分:3)

我不认为你可以在执行当前内核中的文件时使用%run magic命令。

Nbconvert有一个执行API,允许您执行笔记本。因此,您可以创建一个shell脚本来执行所有笔记本,如下所示:

#!/bin/bash
jupyter nbconvert --to notebook --execute 1_py3.ipynb
jupyter nbconvert --to notebook --execute 2_py3.ipynb
jupyter nbconvert --to notebook --execute 3_py3.ipynb
jupyter nbconvert --to notebook --execute 4_R.ipynb

由于您的笔记本电脑不需要共享状态,因此这应该没问题。或者,如果您真的想在笔记本中使用它,可以使用execute Python API从笔记本中调用nbconvert。

import nbformat
from nbconvert.preprocessors import ExecutePreprocessor

with open("1_py3.ipynb") as f1, open("2_py3.ipynb") as f2, open("3_py3.ipynb") as f3, open("4_R.ipynb") as f4:
    nb1 = nbformat.read(f1, as_version=4)
    nb2 = nbformat.read(f2, as_version=4)
    nb3 = nbformat.read(f3, as_version=4)
    nb4 = nbformat.read(f4, as_version=4)

ep_python = ExecutePreprocessor(timeout=600, kernel_name='python3')
#Use jupyter kernelspec list to find out what the kernel is called on your system
ep_R = ExecutePreprocessor(timeout=600, kernel_name='ir')

# path specifies which folder to execute the notebooks in, so set it to the one that you need so your file path references are correct
ep_python.preprocess(nb1, {'metadata': {'path': 'notebooks/'}})
ep_python.preprocess(nb2, {'metadata': {'path': 'notebooks/'}})
ep_python.preprocess(nb3, {'metadata': {'path': 'notebooks/'}})
ep_R.preprocess(nb4, {'metadata': {'path': 'notebooks/'}})

with open("1_py3.ipynb", "wt") as f1, open("2_py3.ipynb", "wt") as f2, open("3_py3.ipynb", "wt") as f3, open("4_R.ipynb", "wt") as f4:
    nbformat.write(nb1, f1)
    nbformat.write(nb2, f2)
    nbformat.write(nb3, f3)
    nbformat.write(nb4, f4)

请注意,这只是从nbconvert执行API文档中复制的示例:link

答案 1 :(得分:0)

我能够使用the answer实现两个解决方案,从python3笔记本运行R笔记本。

1。从! shell命令

调用nbconvert

向python3笔记本添加一个简单的! shell命令:

!jupyter nbconvert --to notebook --execute r.ipynb

因此笔记本看起来像这样:

  1. %run '1_py3.ipynb'
  2. %run '2_py3.ipynb'
  3. %run '3_py3.ipynb'
  4. !jupyter nbconvert --to notebook --execute 4_R.ipynb
  5. 这似乎简单易用。

    2。在单元格中调用nbformat

    将其添加到批处理笔记本中的单元格:

    import nbformat
    from nbconvert.preprocessors import ExecutePreprocessor
    
    rnotebook = "r.ipynb"
    rnotebook_out = "r_out.ipynb"
    rnotebook_path = '/home/jovyan/work/'
    
    with open(rnotebook) as f1:
        nb1 = nbformat.read(f1, as_version=4)
    
    ep_R = ExecutePreprocessor(timeout=600, kernel_name='ir')
    ep_R.preprocess(nb1, {'metadata': {'path': rnotebook_path}})
    
    with open(rnotebook_out, "wt") as f1:
        nbformat.write(nb1, f1)
    

    这是基于Louise Davies(基于nbcovert docs示例)的答案,但它只处理一个文件 - 非R文件可以在%run的单独单元格中处理。 / p>

    如果批处理笔记本与其正在执行的笔记本位于同一文件夹中,则可以使用%pwd shell magic设置路径变量,该魔法将返回批处理笔记本的路径。

    当我们使用nbformat.write时,我们选择更换原始笔记本(这既方便又直观,但可能损坏或破坏文件)并创建一个新的输出文件。如果不需要单元格输出(例如,在操作文件和写入日志的工作流程中),则第三个选项是忽略完全写入单元格输出。

    缺点

    这两种方法的一个缺点是它们不会将单元格结果传回主笔记本显示器 - 而不是%run在结果单元格中显示笔记本输出的方式。 !jupyter nbconvert方法似乎显示来自nbconvert的stdout,而import nbconvert方法则没有显示任何内容。