仅作为文件的一部分

时间:2012-08-31 12:01:05

标签: r read-eval-print-loop

我的R工作流通常是这样的,我打开一个文件,我输入R命令,我想在一个单独打开的R shell中执行这些命令。

最简单的方法是在R中说source('the-file.r')。但是,这总是会重新加载整个文件,如果处理大量数据,这可能需要相当长的时间。它还要求我再次指定文件名。

理想情况下,我只想从文件中获取特定行(或行)(我正在使用复制和粘贴不起作用的终端)。

source似乎没有提供此功能。还有另一种方法可以达到这个目的吗?

2 个答案:

答案 0 :(得分:12)

这是R的另一种方式:

source2 <- function(file, start, end, ...) {
    file.lines <- scan(file, what=character(), skip=start-1, nlines=end-start+1, sep='\n')
    file.lines.collapsed <- paste(file.lines, collapse='\n')
    source(textConnection(file.lines.collapsed), ...)
}

答案 1 :(得分:4)

使用正确的工具......

正如评论中所讨论的,真正的解决方案是使用允许获取文件特定部分的IDE。现有许多解决方案:

作为一个特别的注意事项,上述所有解决方案都可以在本地和服务器上运行(比如通过SSH连接访问)。 R甚至可以在HPC群集上运行 - 如果设置正确,它仍然可以与IDE通信。

...或...

如果由于某种原因,上述解决方案都不起作用,这里的a small module[gist]可以完成这项工作。不过,我一般不建议使用它。 1

#' (Re-)source parts of a file
#'
#' \code{rs} loads, parses and executes parts of a file as if entered into the R
#' console directly (but without implicit echoing).
#'
#' @param filename character string of the filename to read from. If missing,
#' use the last-read filename.
#' @param from first line to parse.
#' @param to last line to parse.
#' @return the value of the last evaluated expression in the source file.
#'
#' @details If both \code{from} and \code{to} are missing, the default is to
#' read the whole file.
rs = local({
    last_file = NULL

    function (filename, from, to = if (missing(from)) -1 else from) {
        if (missing(filename)) filename = last_file

        stopifnot(! is.null(filename))
        stopifnot(is.character(filename))

        force(to)
        if (missing(from)) from = 1

        source_lines = scan(filename, what = character(), sep = '\n',
                            skip = from - 1, n = to - from + 1,
                            encoding = 'UTF-8', quiet = TRUE)
        result = withVisible(eval.parent(parse(text = source_lines)))

        last_file <<- filename # Only save filename once successfully sourced.
        if (result$visible) result$value else invisible(result$value)
    }
})

用法示例:

# Source the whole file:
rs('some_file.r')
# Re-soure everything (same file):
rs()
# Re-source just the fifth line:
rs(from = 5)
# Re-source lines 5–10
rs(from = 5, to = 10)
# Re-source everything up until line 7:
rs(to = 7)

1 有趣的故事:我最近发现自己处于一个混乱配置的集群中,这使得无法安装所需的软件,但由于迫在眉睫的截止日期而迫切需要调试R工作流程。我真的别无选择,只能手动将R代码行复制并粘贴到控制台中。 这个是一种上述情况可能派上用场的情况。是的,这确实发生了。