RMarkdown:如何在Python代码块上使用knitr :: purl()?

5

我想将RMarkdown中的Python代码块导出到外部文件。 knitr::purl() 可以实现这一点,但是我只能使它在R代码块上起作用。 它仅适用于R以外的其他语言吗?

例如,从下面的代码中,将Python代码导出为 my_script.py 文件。

---
title: "Untitled"
output: html_document
---

## Header

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco laboris nisi ut aliquip

```{python}
x = 10
y = 20

z = x + y
print(z)
```
1个回答

8

目前的purl输出非R代码注释。因此,我们需要重新定义输出函数来覆盖这一点。

以下是一个简单的脚本,它(1)只输出Python代码,(2)去掉文档注释(我从knitr源代码中获取了该函数并进行了修改):

library("knitr")

# New processing functions
process_tangle <- function (x) { 
    UseMethod("process_tangle", x)
}

process_tangle.block <- function (x) {
    params = opts_chunk$merge(x$params)

    # Suppress any code but python
    if (params$engine != 'python') {
        params$purl <- FALSE
    }
    if (isFALSE(params$purl)) 
        return("")
    label = params$label
    ev = params$eval
    code = if (!isFALSE(ev) && !is.null(params$child)) {
        cmds = lapply(sc_split(params$child), knit_child)
        one_string(unlist(cmds))
    }
    else knit_code$get(label)
    if (!isFALSE(ev) && length(code) && any(grepl("read_chunk\\(.+\\)", 
        code))) {
        eval(parse_only(unlist(stringr::str_extract_all(code, 
            "read_chunk\\(([^)]+)\\)"))))
    }
    code = knitr:::parse_chunk(code)
    if (isFALSE(ev)) 
        code = knitr:::comment_out(code, params$comment, newline = FALSE)
    # Output only the code, no documentation
    return(knitr:::one_string(code))
}

# Reassign functions
assignInNamespace("process_tangle.block",
                  process_tangle.block,
                  ns="knitr")

# Purl
purl("tmp.Rmd", output="tmp.py")

这是我的tmp.Rmd文件。请注意,它有一个R代码块,但我不希望在结果中显示:

---
title: "Untitled"
output: html_document
---

## Header

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco laboris nisi ut aliquip

```{python}
#!/usr/bin/env python
# A python script
```

```{python} 
x = 10
y = 20

z = x + y
print(z)
```

```{r}
y=5
y
```

运行Rscript extract.R,我得到了tmp.py

#!/usr/bin/env python
# A python script

x = 10
y = 20

z = x + y
print(z)

PS:我在搜索解决同样问题时找到了这个问题。由于没有人回答,所以我开发了自己的解决方案 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接