在不同语言中定义的knitr中的块之间混合变量/结果?

时间:2013-07-31 23:52:23

标签: python r knitr

Language engines是一个很棒的knitr功能。我们可以使用knitr中的任何语言,包括但不限于R. 但是如果我想使用在一个chunck中定义的结果/变量,在另一个chunck中使用相同的语言或其他语言(更性感的选项)该怎么办? )?

最好用一些代码来解释我的想法。在这里,我定义了4个块,其中2个在 python 中,2个在 R 中。

首先我在python中定义一个变量x

## I define engien path explicitly here (TODO: set it globally)
```{r,engine='python',engine.path='C:/Anaconda/python.exe' }
x = 1
print x
```
## 1

现在尝试在新的python chunck中使用x:

```{r,engine='python',engine.path='C:/Anaconda/python.exe' }
x = x +1
print x

```

没有错误,但结果令人惊讶,看起来x在这里是NULL。现在,如果我尝试在新的R chunck中使用x:

```{r fig.width=7, fig.height=6}
x +1
y = 2
```
## Error: object 'x' not found 

我收到错误。现在如果我尝试在新的R块中使用y并且它工作正常。 r引擎可以使用前一个R chunck中定义的变量。请注意,这不适用于python。

```{r fig.width=7, fig.height=6}
y+3
```
## [1] 5

为什么R和python之间的行为存在差异?它是结构性的,因为R的范围规则还是仅仅是knitr中尚未实现的未来?或者也许是一个错误?

2 个答案:

答案 0 :(得分:8)

这是记录在案的行为。

请参阅http://yihui.name/knitr/demo/engines/

  

除了engine ='R'(默认),所有块都是单独执行的   会话,因此无法直接共享变量。如果我们想   利用在以前的块中创建的对象,我们通常必须这样做   将它们写入文件(作为副作用)。对于bash引擎,我们可以使用   Sys.setenv()将变量从R导出到bash(示例)

答案 1 :(得分:1)

你可以在python的启动(PYTHONSTARTUP)文件中放置一些东西。当退出利用atexit时,精心设计的启动文件可以导出文件中的所有已知变量。

这是一个打印所有新全局变量的配方:

>>> import atexit
>>> def list_globals(known_globals=globals().keys()):
...     new_globals = set(globals().keys())
...     new_globals -= set(known_globals)
...     for key in new_globals:
...        print '%s=%s' % (key, globals()[key])
... 
>>> atexit.register(list_globals)
<function list_globals at 0x107140e60>
>>> del list_globals
>>> del atexit
>>> 

以上是运行上述代码后的示例会话。

>>> 
>>> def foo():
...    a  = 1
... 
>>> b = 2
>>> ^D
b=2
foo=<function foo at 0x107140d70>

您可以改为使用文件/套接字/消息队列/等。