7

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

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

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

## 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 块中使用 x:

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

```

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

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

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

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

为什么这里 R 和 python 之间的行为存在差异?它是由于 R 范围规则而导致的结构性,还是只是尚未在 knitr 中实现的未来?或者可能是一个错误?

4

2 回答 2

8

这是记录在案的行为。

http://yihui.name/knitr/demo/engines/

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

于 2013-08-01T00:20:14.503 回答
1

您可以在PYTHONSTARTUPpython 的启动 () 文件中添加一些内容。一个精心制作的启动文件可以在退出杠杆时导出文件中的所有已知变量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>

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

于 2013-08-15T07:41:51.693 回答