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中尚未实现的未来?或者也许是一个错误?
答案 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>
您可以改为使用文件/套接字/消息队列/等。