Избегайте загрузки данных каждый раз в Knitr

Я создаю документ с помощью Knitr, и мне утомительно перезагружать данные с диска каждый раз, когда я анализирую документ, пока я в разработке. Я подмножил этот файл данных для разработки, чтобы сократить время загрузки. У меня также включен кеш вязания.

Я попытался назначить данные глобальной среде с помощью <<- и с помощью exists с where=globalenv(), но это не сработало.

Кто-нибудь знает, как использовать предварительно загруженные данные из среды в Knitr или есть другие идеи для ускорения разработки?


person Daniel    schedule 21.09.2014    source источник


Ответы (1)


Когда документ вяжется, внутри R создается новая среда, и поэтому никакие настройки в глобальной среде не будут переданы в документ. Однако это делается преднамеренно, так как случайная ссылка на объект в глобальной среде может легко нарушить воспроизводимый анализ, и, следовательно, создание чистой сессии каждый раз означает, что файл RMarkdown запускается сам по себе, независимо от настроек глобальной среды.

Если у вас есть вариант использования, который оправдывает предварительную загрузку данных, вы можете сделать несколько вещей.

Пример данных

Во-первых, я создал минимальный файл Rmd, как показано ниже, под названием «RenderTest.Rmd»:

title: "Render"
author: "Michael Harper"
date: "7 November 2017"
output: pdf_document
---

```{r cars}
summary(cars2)
```

В этом примере cars2 — это набор данных, на которые я ссылаюсь из своего глобального сеанса. Запустите его с помощью команды «Вязать» в RStudio, это вернет следующую ошибку:

Ошибка в сводке (автомобили): объект «cars2» не найден: ... withCallignHandlers -> withVisible -> eval -> eval -> summary Выполнение остановлено

Вариант 1. Вызов функции рендеринга вручную

Функцию render из rmarkdown можно вызвать из другого сценария R. По умолчанию это не создает новую среду для запуска сценария, поэтому вы можете использовать любые уже загруженные параметры. Например:

# Build file
library(rmarkdown)

cars2<- cars
render("RenderTest.Rmd")

Однако я бы поостерегся делать это. Во-первых, преимущество использования RMarkdown заключается в том, что воспроизводимость скрипта становится невероятно простой. Как только вы начинаете использовать внешние скрипты, это усложняет репликацию, поскольку все настройки не содержатся в файле.

Вариант 2. Сохранение данных в объект R

Если у вас есть какой-то анализ, выполнение которого требует времени, вы можете сохранить результат анализа как объект R, а затем перезагрузить окончательную версию данных в сеанс. Используя мой пример выше:

```{r dataProcess, cache = TRUE}
cars2 <- cars
save(cars2, "carsData.RData") # saves the 'cars2' dataset
```
and then we can just reload the data into the session:

```{r}
load("carsData.RData") # reloads the 'cars2' dataset
```

Я предпочитаю эту технику. Фрагмент dataProcess кэшируется, поэтому запускается только в случае внесения изменений в код. Результаты сохраняются в файл, который затем загружается следующим фрагментом. Данные все еще должны быть загружены в сеанс, но вы можете сохранить окончательный набор данных, если вам нужно выполнить какую-либо очистку данных.

Вариант 3. Создавайте файл реже

Благодаря обновлениям, внесенным в RStudio за последние несколько лет, потребность в постоянном восстановлении файла уменьшилась. Чанки можно запускать непосредственно в файле и просматривать окно вывода. Потенциально это сэкономит вам много времени, пытаясь оптимизировать скрипт, только для того, чтобы сэкономить пару минут на компиляции (что обычно дает хорошее время, чтобы выпить горячий напиток!).

введите описание изображения здесь

person Michael Harper    schedule 07.11.2017
comment
это отличный ответ. По крайней мере, в моей текущей версии R 4.0.3 вызов save требует указания аргумента file: save(cars2, file = "carsData.RData") - person tjebo; 04.03.2021
comment
Кроме того, для будущего читателя вы можете вместо этого рассмотреть возможность сохранения в виде файла .rds, см. обсуждение здесь: stackoverflow.com/questions/19967478/ - person tjebo; 04.03.2021