Источник только часть файла

Рабочий процесс My R обычно таков, что у меня есть открытый файл, в который я набираю команды R, и Id нравится выполнять эти команды в отдельно открытой оболочке R.

Самый простой способ сделать это - сказать source('the-file.r') внутри R. Однако это всегда перезагружает весь файл, который может занять значительное время, если обрабатываются большие объемы данных. Это также требует, чтобы я снова указал имя файла.

В идеале, Id хочет вывести только строку (или строки) из файла (Im работает на терминале, где copy & paste не работает).

source, похоже, не предлагает эту функциональность. Есть ли другой способ достичь этого?

Ответ 1

Используя правильный инструмент для задания...

Как обсуждалось в комментариях, реальным решением является использование среды IDE, которая позволяет находить определенные части файла. Существует много существующих решений:

  • Для Vim, theres Nvim-R. p >

  • Для Emacs theres ESS.

  • И, конечно же, превосходная автономная RStudio IDE.

    /li >

В качестве особого замечания все вышеупомянутые решения работают как локально, так и на сервере (например, через SSH-соединение). R может даже запускаться в кластере HPC - он все равно может взаимодействовать с IDE, если он настроен правильно.

... или... не.

Если по какой-либо причине ни одно из вышеперечисленных решений не работает, heres небольшой модуль [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-кода в консоль вручную. Это ситуация, в которой это может пригодиться. И да, это действительно произошло.

Ответ 2

Здесь другой способ с 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), ...)
}