R

Десять экономящих время R-хаков

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

Чем больше я кодирую, тем более чувствительным к неэффективности я становлюсь. Для меня Nirvana - это то место, где вы можете очень быстро кодировать, не делая ничего кроме вашего любимого редактора кода.

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

Вот десять приемов, которые я регулярно использую, чтобы свести к минимуму отвлекающие факторы и поддерживать темп работы. Когда я рассказываю об этом некоторым людям, я часто получаю несколько реакций вроде «Почему я не знал об этом?». Так что я надеюсь, что по крайней мере некоторые из них будут для вас новыми и полезными.

1. Скачивание и чтение файлов прямо из источника.

Этот совет должен помочь вам минимизировать время на администрирование локальных файлов данных и сделать ваш проект более воспроизводимым для других. Если у вас есть файл данных, который находится где-то в Интернете, например, на Google Диске или каком-либо другом URL-адресе, пакет readr позволяет вам читать его прямо из URL-адреса в фрейм данных, используя такие функции, как read_csv() или read_rds(). Например:

my_df <- readr::read_csv(url("https://www.website.com/data.csv"))

Если данные находятся в репозитории Github, вы можете загрузить необработанный файл, добавив ?raw=true к URL-адресу, поэтому вот как вы могли бы получить некоторые данные о скоростном датировании из одного из моих репозиториев Github:

speed_dating_data <- readr::read_rds("https://github.com/keithmcnulty/speed_dating/blob/master/speed_data_data.RDS?raw=true")

Если у вас есть файл странного типа, который readr не может обработать, вы можете просто использовать download.file() функцию базового R, чтобы поместить его в свой сеанс, где вы затем можете прочитать его, используя любой правильный пакет. Для этого вам не нужна функция url, поэтому, чтобы использовать ее для загрузки моих данных быстрого знакомства:

download.file("https://github.com/keithmcnulty/speed_dating/blob/master/speed_data_data.RDS?raw=true", destfile = "speed_dating_data.RDS") 
speed_dating_data <- readRDS("speed_dating_data.RDS")

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

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

2. Хранение ваших учетных данных для регулярного использования.

Если вы часто вводите пароли к базам данных или другим службам, то вы зря теряете время, а если они отображаются в вашем коде, то это просто плохая практика. В R есть скрытый файл с именем .Renviron, в котором вы можете хранить учетные данные в своей глобальной среде, чтобы вам не приходилось постоянно вводить их или открывать.

Лучший способ работать с .Renviron - использовать функцию edit_r_environ() пакета usethis. Это немедленно откроет ваш .Renviron файл в сеансе, чтобы вы могли добавить переменные среды. В качестве примера предположим, что у вас есть пароль базы данных, который вы часто используете. В .Renviron введите это в новой строке:

MY_DB_PWD="[your password]"

Затем в вашем коде вам просто нужно ввести это вместо вашего пароля:

Sys.getenv("MY_DB_PWD")

Помните, что всякий раз, когда вы сохраняете новую переменную среды в .Renviron, вам необходимо перезапустить R, чтобы она вступила в силу. Вы можете использовать это для всех видов вещей, таких как вход в базу данных, учетные данные API, учетные данные блога и т. Д.

3. Сочетания клавиш RStudio.

Многие люди не знают о сочетаниях клавиш в RStudio. Они могут сэкономить очень много времени на кодирование.

Один важный момент - Ctrl-Shift-M для функции канала %>%. Я всегда получаю хотя бы одно «как я не узнал об этом?» когда я рассказываю об этом людям. Другой вариант - Option-- (или Alt--) для назначения <-. (Я очень надеюсь, что вы не используете для этого =!).

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

Вы можете найти полный список горячих клавиш RStudio здесь. Это как мешок удовольствия для программистов.

4. Параметры глобальных фрагментов в RMarkdown

Если я пишу в RMarkdown, я часто обнаруживаю, что какие бы параметры фрагментов я не выбрал для своего документа, они будут одинаковыми для всех фрагментов. Так что в одном документе я могу повторить свой код или не хочу отображать предупреждения или сообщения.

Вместо того, чтобы вводить эти параметры в каждый фрагмент документа, я могу установить их как глобальные параметры фрагмента в моем первом фрагменте кода. Вот пример того, как это сделать:

knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE)

5. Простая вставка ggplots с помощью пакета patchwork

Если вы объединяете несколько ggplots, пакет patchwork использует интуитивно понятную и простую грамматику, так что вам не нужно использовать более сложные функции, такие как grid.arrange(). Он также имеет больше возможностей, чем cowplot, для обработки сложных макетов.

С каждым графиком, назначенным объекту, вы можете использовать такие символы, как | и /, чтобы указать, что вы хотите выровнять в столбцах и что вы хотите в строках, и пакет выполнит выравнивание за вас. Вот пример из репозитория пакета Github с использованием mtcars:

library(ggplot2)
library(patchwork)
p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
p3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec)) 
p4 <- ggplot(mtcars) + geom_bar(aes(carb)) 
(p1 | p2 | p3) / 
      p4

6. Более плавное управление зависимостями с помощью Renv

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

Пакет Renv обеспечивает гораздо более простой и понятный способ решения этой проблемы по сравнению с packrat, предыдущим решением для управления зависимостями пакетов.

Когда вы разработали свой проект до определенного момента и думаете, что вам или кому-то другому, возможно, придется вернуться к нему снова в будущем, запустив renv::init(), вы можете получить все зависимости вашего пакета и версии, обнаруженные и сохраненные в файле с именем renv.lock , которые вы должны оставить в репо проекта. Позже, запустив renv::restore(), вы сможете переустановить все зависимости из renv.lock, чтобы убедиться, что вы настроили свой проект как можно ближе к тому месту, где вы его оставили, и значительно снизив вероятность возникновения проблем, связанных с версии пакета. Так просто, так важно и так эффективно.

7. Многозадачность с заданиями RStudio.

Вы, наверное, слышали, что R является однопоточным, и это может вызвать проблемы. Это правда, что если вы выполните команду с интенсивными вычислениями в консоли, вы можете заблокировать сеанс R до тех пор, пока команда не будет завершена.

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

Но для большинства обычных программистов R, вероятно, наиболее полезным событием было введение Jobs в RStudio 1.2.

Если у вас есть длинный скрипт R, который вам нужно выполнить полностью, но вы все еще хотите делать другие вещи на своей консоли, вы увидите, что в версии 1.2 RStudio кнопка Source теперь имеет раскрывающееся меню, в котором вы можете найти сценарий как «Местное задание». Это в основном запустит ваш скрипт в другом сеансе R, что позволит вам работать в существующем сеансе.

Имейте в виду, что после завершения задания все созданные им объекты исчезнут, поэтому, если вы не записали то, что вам нужно, в базу данных или файловую систему, вы потеряете это. Если вы хотите изучить объекты, созданные во время локального задания, вам нужно будет сохранить изображение рабочего пространства сеанса в Rdata файл в конце сценария с помощью функции save().

Пока скрипт запущен, вы можете отслеживать его ход, используя зеленые полосы, отображаемые в окне заданий, и если вы комментируете свой скрипт с разделами кода (комментарии, которые имеют не менее трех конечных тире), окно задания будет отображать комментарии по мере его прохождения. сценарий, чтобы вы могли точно видеть, где он находится.

(Если вы работаете на сервере / рабочей среде RStudio, вы также можете использовать Launcher Jobs для запуска вашего скрипта в вычислительной инфраструктуре, если у вас есть доступ к одной - очень удобно!)

Подробнее о вакансиях здесь.

8. Переименуйте все переменные в области видимости.

Это, вероятно, вписывается в более ранний раздел о сочетаниях клавиш RStudio, но я думаю, что он заслуживает отдельного раздела. Итак, вы решаете переименовать один из своих объектов и затем понимаете, что этот объект появляется в вашем коде еще двадцать раз, и поэтому вам нужно пойти и отредактировать и эти двадцать экземпляров - звучит знакомо?

Попробуйте выделить имя объекта, а затем Ctrl-Alt-Shift-M (или Ctrl-Option-Shift-M). Вы сразу увидите, что любые изменения, которые вы сейчас вносите в свой объект, будут изменены везде, где этот объект появляется в вашей текущей области. Добро пожаловать 😊

9. Использование . для удержания трубопроводов

Благодаря широкому использованию конвейеров в R-коде и тому факту, что большинство функций tidyverse получают объект в качестве своего первого аргумента, люди, похоже, забыли о том, как использовать . в своем R-коде. Например, я часто вижу, как программисты прекращают работу по конвейеру, как только приходят к функции, которая не принимает объект в качестве первого аргумента. Они переходят на новую строку кода и ломают трубку.

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

vec <- c("hello", "jello", "is", "great") 
vec %>% grepl("lo", .) 
[1] TRUE TRUE FALSE FALSE

10. Немедленно вызываемый дисплей

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

## What I usually see 
mt_count <- mtcars %>% dplyr::count(cyl) 
mt_count 
# A tibble: 3 x 2
    cyl     n
  <dbl> <int>
1     4    11
2     6     7
3     8    14
## Immediately invoked display 
(mt_count <- mtcars %>% dplyr::count(cyl)) 
# A tibble: 3 x 2
    cyl     n
  <dbl> <int>
1     4    11
2     6     7
3     8    14

Есть ли у вас какие-нибудь способы сэкономить время на R-хаках? Не стесняйтесь добавлять их в комментарии.

Изначально я был чистым математиком, затем стал психометриком и специалистом по анализу данных. Я увлечен применением всех этих дисциплин к сложным человеческим вопросам. Я также помешан на программировании и большой поклонник японских ролевых игр. Найдите меня в LinkedIn или Twitter. Также посетите мой блог на drkeithmcnulty.com.