Как задать хороший вопрос в R чате?

R
Author

Elena U

Published

December 2, 2022

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

Reprex (reproducible example) – это минимальный пример кода, воспроизводящий ошибку или описывающий, что требуется сделать.

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

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

Установка: install.packages('reprex')

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

У репрекса есть три важных свойства:

Например:

reprex::reprex({
    mtcars %>% 
        filter(mpg > 20) %>% 
        group_by(cyl) %>% 
        summarise(mpg)
})

При попытке запустить такой код у меня сразу появилось, что нет функции %>%, даже если пайп работал до этого. Репрекс создает совершенно новую сессию и поэтому необходимо загрузить все пакеты и объявить все переменные, даже если они уже были загружены и объявлены в скрипте. Соответственно, от своих реальных данных, на которых произошла ошибка, нужно взять минимальный воспроизводимый пример. Обычно я создаю игрушечные датасеты df <- data.frame(a = 1:10, b = letters[1:10]), на которых воссоздаю ошибку. Также можно использовать встроенные датасеты, например mtcars, iris.

Созданный с помощью функции reprex::reprex() код можно сразу же копировать в телеграм-чат, оформление как код будет сразу же задано с помощью трех бэктиков ```. Однако в новых версиях телеграма появилась подсветка синтаксиса, если вставить код с указанием языка после трех бэктиков ```r, что максимально облегчает работу с кодом и повышает вероятность, что вам смогут помочь с запросом.

В случае если данные все же очень сложные, то можно воспользоваться функцией dput. Например, взять первые несколько строк head-ом и поместить в dput: dput(head(mtcars)), где вместо mtcars ваши данные. В результате будет сложная выдача structure(list...), которую можно скопировать и в репрексе создать такую переменную.

reprex::reprex({
    library(dplyr)
    df <- structure(list(mpg = c(21, 21, 22.8, 21.4, 18.7, 18.1), cyl = c(6, 6, 4, 6, 8, 6), 
    disp = c(160, 160, 108, 258, 360, 225), hp = c(110, 110, 93, 110, 175, 105), 
    drat = c(3.9, 3.9, 3.85, 3.08, 3.15, 2.76), wt = c(2.62, 2.875, 2.32, 3.215, 3.44, 3.46),
    qsec = c(16.46, 17.02, 18.61, 19.44, 17.02, 20.22), vs = c(0, 0, 1, 1, 0, 1), 
    am = c(1, 1, 1, 0, 0, 0), gear = c(4, 4, 4, 3, 3, 3), 
    carb = c(4,4, 1, 1, 2, 1)), 
    row.names = c("Mazda RX4", "Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Valiant"), class = "data.frame")
    df %>% filter(mpg > 20)
}) 

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

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

Вообще создание репрекса может занять много времени, но это является крайне полезным. Несколько раз я начинала писать вопрос, создавала репрекс и на этапе создания понимала, в чем ошибка, в итоге репрекс помог сам по себе, даже без обращения к участникам чатов. Один раз успела отправить сообщение и при перечитывании поняла, что было не так, но мне уже успели ответить, не стала удалять.

Ответы на часто (один раз) задаваемые вопросы:

Вопрос 1: почему бы просто не скинуть таблицу и образец своего скрипта, тогда можно будет сразу на реальных данных показать все?

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

Вопрос 2: почему бы не использовать .RData?

Ответ: в целом, рдату использовать чуть лучше, но все же минусы про файловую систему остаются актуальными. Плюс идея репрекса в минимизации и изолировании примера, чтобы оставались только проблемные строки и столбцы, для фокусировки внимания.

Еще парочка ссылок: инструкция от Хэдли, пример создания репрекса на shiny, слайды и 50-минутное видео о репрексах от Дженни Брайан (презентация очень крутая, наиболее информативная, советую посмотреть).

В общем, рекомендую использовать этот подход, тогда освоение R будет более приятным и успешным. На стаковерфлоу результат репрекса тоже можно забрасывать, я думаю, но возможно туда еще нужно указать результаты sessionInfo() (поправьте в комментариях, если не так). Сама новые вопросы на стаковерфлоу не писала, хватает обычно уже существующих для моих задач.

Подписывайтесь на телеграм-канал: https://t.me/stats_for_science, будет много интересного.