При обсуждении производительности с коллегами, обучении, отправке отчета об ошибках или поиске руководства в списках рассылки и здесь, в Переполнении стека, часто задают воспроизводимый пример и всегда помогают.
Каковы ваши советы по созданию отличного примера? Как вы вставляете структуры данных изрв текстовом формате? Какую другую информацию вы должны включить?
Есть ли другие приемы помимо использования dput()
, dump()
или structure()
? Когда вы должны включить library()
или require()
заявления? Какие зарезервированные слова следует один избежать, в дополнение к c
, df
, data
и т.д.?
Как сделать великий р Воспроизводимый пример?
Ответы:
Минимальный воспроизводимый пример состоит из следующих элементов:
set.seed()
) для воспроизводимости 1Примеры хороших минимальных воспроизводимых примеров см. В файлах справки используемой вами функции. В общем, весь приведенный там код отвечает требованиям минимального воспроизводимого примера: данные предоставляются, минимальный код предоставляется, и все работает. Также посмотрите на вопросы о переполнении стека с большим количеством голосов.
Создание минимального набора данных
В большинстве случаев это легко сделать, просто предоставив вектор / фрейм данных с некоторыми значениями. Или вы можете использовать один из встроенных наборов данных, которые поставляются с большинством пакетов.
Полный список встроенных наборов данных можно увидеть с
library(help = "datasets")
. Существует краткое описание каждого набора данных, и можно получить дополнительную информацию, например,?mtcars
где «mtcars» является одним из наборов данных в списке. Другие пакеты могут содержать дополнительные наборы данных.Сделать вектор легко. Иногда необходимо добавить некоторую случайность, и для этого есть целый ряд функций.
sample()
может рандомизировать вектор или дать случайный вектор только с несколькими значениями.letters
полезный вектор, содержащий алфавит Это может быть использовано для создания факторов.Несколько примеров:
x <- rnorm(10)
для нормального распределения,x <- runif(10)
для равномерного распределения, ...x <- sample(1:10)
для вектора 1:10 в случайном порядке.x <- sample(letters[1:4], 20, replace = TRUE)
Для матриц можно использовать
matrix()
, например:Создание фреймов данных может быть сделано с помощью
data.frame()
. Следует обратить внимание на имена записей во фрейме данных и не усложнять их.Пример :
Для некоторых вопросов могут потребоваться конкретные форматы. Для них можно использовать любой из предусмотренных
as.someType
функций:as.factor
,as.Date
,as.xts
, ... Это , в сочетании с векторными и / или кадров данных уловок.Скопируйте ваши данные
Если у вас есть какие - то данные , которые были бы слишком трудно построить , используя эти советы, то вы всегда можете сделать подмножество исходной информации, используя
head()
,subset()
или индексы. Затем используйте,dput()
чтобы дать нам что-то, что можно сразу поместить в R:Если у вашего фрейма данных есть фактор с множеством уровней,
dput
вывод может быть громоздким, потому что он по-прежнему будет перечислять все возможные уровни факторов, даже если их нет в подмножестве ваших данных. Чтобы решить эту проблему, вы можете использоватьdroplevels()
функцию. Ниже обратите внимание, как вид является фактором только с одним уровнем:При использовании
dput
вы также можете включить только соответствующие столбцы:Еще одно предостережение в
dput
том, что он не будет работать дляdata.table
объектов с ключами или сгруппированныхtbl_df
(классgrouped_df
) изdplyr
. В этих случаях вы можете преобразовать обратно в обычный фрейм данных перед совместным использованиемdput(as.data.frame(my_data))
.В худшем случае, вы можете дать текстовое представление, которое можно прочитать, используя
text
параметрread.table
:Создание минимального кода
Это должно быть легкой частью, но часто это не так. Что вы не должны делать, это:
Что вы должны сделать, это:
library()
)unlink()
)op <- par(mfrow=c(1,2)) ...some code... par(op)
)Дать дополнительную информацию
В большинстве случаев достаточно версии R и операционной системы. Когда возникают конфликты с пакетами, предоставление вывода
sessionInfo()
может действительно помочь. Говоря о соединениях с другими приложениями (будь то через ODBC или что-то еще), следует также указать номера версий для них и, если возможно, необходимую информацию о настройке.Если вы работаете R в R Studio , используя
rstudioapi::versionInfo()
может быть полезным , чтобы сообщить свою версию RStudio.Если у вас есть проблема с конкретным пакетом, вы можете указать версию пакета, указав вывод
packageVersion("name of the package")
.1 Примечание: вывод
set.seed()
отличается между R> 3.6.0 и предыдущими версиями. Укажите, какую версию R вы использовали для случайного процесса, и не удивляйтесь, если вы получите несколько отличающиеся результаты при ответе на старые вопросы. Чтобы получить такой же результат в таких случаях, вы можете использоватьRNGversion()
-функцию раньшеset.seed()
(например :)RNGversion("3.5.2")
.источник
dput
если датафрейм очень большой и проблема генерируется серединой фрейма? Есть ли способ использоватьdput
для воспроизведения средней части данных, скажем, строки с 60 по 70?tmp <- mydf[50:70,]
последующимdput(mydf)
. Если кадр данных действительно большой, попробуйте выделить проблему и просто отправьте несколько строк, которые вызывают проблему.head
илиdput
ограничить данные до уровня N рекурсивно? Я пытаюсь придумать воспроизводимый пример, и мои данные представляют собой список фреймов данных. Так что,dput(head(myDataObj))
похоже, этого недостаточно, поскольку он генерирует выходной файл размером 14 МБ.(Вот мой совет от Как написать воспроизводимый пример . Я попытался сделать его коротким, но приятным)
Как написать воспроизводимый пример.
Скорее всего, вы получите хорошую помощь по проблеме R, если предоставите воспроизводимый пример. Воспроизводимый пример позволяет кому-то другому воссоздать вашу проблему, просто скопировав и вставив код R.
Чтобы сделать ваш пример воспроизводимым, необходимо включить четыре вещи: необходимые пакеты, данные, код и описание вашей среды R.
Пакеты должны быть загружены в верхней части скрипта, поэтому легко увидеть, какие из них нужны в примере.
Самый простой способ включить данные в электронное письмо или вопрос переполнения стека - это использовать
dput()
для генерации кода R для его воссоздания. Например, чтобы воссоздатьmtcars
набор данных в R, я бы выполнил следующие шаги:dput(mtcars)
в Rmtcars <-
затем вставьте.Потратьте немного времени, чтобы ваш код легко читался другими:
убедитесь, что вы использовали пробелы и имена переменных краткие, но информативные
используйте комментарии, чтобы указать, где ваша проблема лежит
сделать все возможное, чтобы удалить все, что не связано с проблемой.
Чем короче ваш код, тем легче его понять.
Включите вывод
sessionInfo()
в комментарии в вашем коде. Это обобщает вашу среду R и позволяет легко проверить, используете ли вы устаревший пакет.Вы можете проверить, действительно ли вы создали воспроизводимый пример, запустив новый сеанс R и вставив в него скрипт.
Прежде чем поместить весь свой код в электронное письмо, подумайте о том, чтобы поместить его на Gist GitHub . Это даст вашему коду хорошую подсветку синтаксиса, и вам не придется беспокоиться о том, что система электронной почты может что-то испортить.
источник
reprex
вtidyverse
это хороший пакет для получения минимальной, воспроизводимый пример: github.com/tidyverse/reprexЛично я предпочитаю «один» лайнер. Нечто подобное:
Структура данных должна имитировать идею проблемы автора, а не точную стенографическую структуру. Я действительно ценю, когда переменные не перезаписывают мои собственные переменные или, не дай бог, функции (например
df
).Кроме того, можно обрезать несколько углов и указать на уже существующий набор данных, что-то вроде:
Не забудьте указать какие-либо специальные пакеты, которые вы можете использовать.
Если вы пытаетесь продемонстрировать что-то на более крупных объектах, вы можете попробовать
Если вы работаете с пространственными данными через
raster
пакет, вы можете генерировать случайные данные. В виньетке упаковки можно найти множество примеров, но вот маленький самородок.Если вам нужен какой-то пространственный объект, реализованный в
sp
, вы можете получить некоторые наборы данных через внешние файлы (например, ESRI shapefile) в «пространственных» пакетах (см. Пространственное представление в представлениях задач).источник
sample
илиrunif
разумноset.seed
. По крайней мере, это предположение я получил при создании примеров, касающихся выборки или генерации случайных чисел.runif
илиsample
не смущенные что они не могут получить те же данные.Вдохновленный этим постом, я теперь использую удобную функцию,
reproduce(<mydata>)
когда мне нужно отправить в StackOverflow.БЫСТРЫЕ ИНСТРУКЦИИ
Если
myData
это имя вашего объекта для воспроизведения, запустите следующее в R:Подробности:
Эта функция является интеллектуальной оболочкой
dput
и выполняет следующие действия:dput
выводobjName <- ...
чтобы его можно было легко скопировать + вставить, но ...Источник доступен здесь:
Пример:
DF составляет около 100 х 102. Я хочу попробовать 10 строк и несколько конкретных столбцов
Дает следующий вывод:
Обратите также внимание на то, что весь вывод находится в хорошей единственной длинной строке, а не в высоком абзаце разделенных строк. Это облегчает чтение сообщений SO с вопросами, а также позволяет легче копировать и вставлять.
Обновление октябрь 2013:
Теперь вы можете указать, сколько строк текста будет занимать (то есть, что вы будете вставлять в StackOverflow). Используйте
lines.out=n
аргумент для этого. Пример:reproduce(DF, cols=c(1:3, 17, 23), lines.out=7)
выходы:источник
Вот хороший гид .
Самый важный момент: просто убедитесь, что вы создали небольшой фрагмент кода, который мы можем запустить, чтобы увидеть, в чем проблема . Полезная функция для этого
dput()
, но если у вас есть очень большие данные, вы можете создать небольшой набор данных или использовать только первые 10 строк или около того.РЕДАКТИРОВАТЬ:
Также убедитесь, что вы сами определили, где проблема. Примером не должен быть весь R-скрипт с «В строке 200 есть ошибка». Если вы используете инструменты отладки в R (я люблю
browser()
) и Google, вы сможете реально определить, где проблема, и воспроизвести тривиальный пример, в котором то же самое происходит не так.источник
Список рассылки R-help содержит руководство по отправке, которое охватывает как вопросы, так и ответы, включая пример создания данных:
Слово маленькое особенно важно. Вы должны стремиться к минимальному воспроизводимому примеру, что означает, что данные и код должны быть максимально простыми, чтобы объяснить проблему.
РЕДАКТИРОВАТЬ: красивый код легче читать, чем уродливый код. Используйте руководство по стилю .
источник
Начиная с R.2.14 (я полагаю), вы можете передать свое текстовое представление данных напрямую
read.table
:источник
Иногда проблема на самом деле не воспроизводима с небольшим фрагментом данных, независимо от того, как сильно вы пытаетесь, и не происходит с синтетическими данными (хотя полезно показать, как вы создали синтетические наборы данных, которые не воспроизводили проблему, потому что это исключает некоторые гипотезы).
Если вы не можете сделать ни то, ни другое, вам, вероятно, нужно нанять консультанта, чтобы решить вашу проблему ...
редактировать : два полезных вопроса для анонимизации / шифрования:
источник
fitdistr
иfitdistrplus
.Ответы до сих пор, очевидно, хороши для воспроизводимости. Это просто для пояснения того, что воспроизводимый пример не может и не должен быть единственным компонентом вопроса. Не забудьте объяснить, как вы хотите, чтобы он выглядел, и контуры вашей проблемы, а не только то, как вы пытались добраться до сих пор. Код не достаточно; тебе тоже нужны слова.
Вот воспроизводимый пример того, чего следует избегать (взятый из реального примера, имена изменены для защиты невинных):
Ниже приведены примеры данных и часть функций, с которыми у меня возникли проблемы.
Как мне этого добиться?
источник
У меня есть очень простой и эффективный способ сделать R пример, который не был упомянут выше. Вы можете определить свою структуру в первую очередь. Например,
Затем вы можете ввести свои данные вручную. Это эффективно для небольших примеров, а не для больших.
источник
dput(mydata)
for (d in data) {...}
.Чтобы быстро создать
dput
ваши данные, вы можете просто скопировать (часть) данных в буфер обмена и запустить следующее в R:для данных в Excel:
для данных в текстовом файле:
Вы можете изменить
sep
в последнем случае, если это необходимо. Это будет работать, только если ваши данные находятся в буфере обмена, конечно.источник
Методические рекомендации:
Ваша главная цель при составлении ваших вопросов должна состоять в том, чтобы сделать читателей как можно проще для понимания и воспроизведения вашей проблемы в своих системах. Для этого:
Это требует некоторой работы, но кажется справедливым компромиссом, поскольку вы просите других сделать работу за вас.
Предоставление данных:
Встроенные наборы данных
Наилучшим вариантом на сегодняшний день является использование встроенных наборов данных. Это позволяет другим легко работать над вашей проблемой. Введите
data()
в приглашении R, чтобы увидеть, какие данные доступны для вас. Несколько классических примеров:iris
mtcars
ggplot2::diamonds
(внешний пакет, но есть почти у всех)Посмотрите этот SO QA, чтобы узнать, как найти наборы данных, подходящие для вашей проблемы.
Если вы можете перефразировать свою проблему, используя встроенные наборы данных, у вас гораздо больше шансов получить хорошие ответы (и положительные отзывы).
Собственные данные
Если ваша проблема очень специфична для типа данных, который не представлен в существующих наборах данных, предоставьте код R, который генерирует наименьший возможный набор данных, в котором ваша проблема проявляется. Например
Теперь кто-то, пытающийся ответить на мой вопрос, может скопировать / вставить эти две строки и немедленно начать работу над проблемой.
dput
В крайнем случае , вы можете использовать
dput
для преобразования объекта данных в код R (напримерdput(myData)
). Я говорю как «последнее средство», потому что выводdput
часто довольно громоздкий, раздражает копирование-вставка и затеняет остальную часть вашего вопроса.Обеспечить ожидаемый результат:
Кто-то однажды сказал:
Если вы можете добавить что-то вроде «Я ожидал получить этот результат»:
на ваш вопрос, люди с большей вероятностью быстро поймут, что вы пытаетесь сделать. Если ваш ожидаемый результат велик и громоздок, то вы, вероятно, недостаточно задумывались о том, как упростить вашу проблему (см. Далее).
Объясните свою проблему кратко
Главное, чтобы максимально упростить вашу проблему, прежде чем задавать вопрос. Перефразирование проблемы для работы со встроенными наборами данных очень поможет в этом отношении. Вы также часто обнаружите, что, пройдя процесс упрощения, вы решите свою собственную проблему.
Вот несколько примеров хороших вопросов:
В обоих случаях проблемы пользователя почти наверняка не связаны с простыми примерами, которые они предоставляют. Скорее они абстрагировали природу своей проблемы и применили ее к простому набору данных, чтобы задать свой вопрос.
Почему еще один ответ на этот вопрос?
Этот ответ сфокусирован на том, что я считаю лучшей практикой: используйте встроенные наборы данных и предоставьте то, что вы ожидаете в результате, в минимальной форме. Наиболее выдающиеся ответы сосредоточены на других аспектах. Я не ожидаю, что этот ответ поднимется до какой-то известности; это здесь исключительно для того, чтобы я мог ссылаться на него в комментариях к вопросам новичка.
источник
Воспроизводимый код - это ключ к получению помощи. Однако есть много пользователей, которые могут скептически относиться к вставке даже части своих данных. Например, они могут работать с конфиденциальными данными или с исходными данными, собранными для использования в исследовательской работе. По какой-то причине я подумал, что было бы неплохо иметь удобную функцию для «деформации» моих данных перед их публичным вставлением.
anonymize
Функция из пакетаSciencesPo
очень глупо, но для меня это хорошо работает сdput
функцией.Тогда я анонимизирую это:
Можно также выбрать несколько переменных вместо целых данных, прежде чем применять команды анонимизации и dput.
источник
Зачастую вам нужны некоторые данные для примера, однако вы не хотите публиковать свои точные данные. Чтобы использовать некоторые существующие data.frame в установленной библиотеке, используйте команду data для их импорта.
например,
а затем сделать проблему
источник
mtcars
иiris
наборы данных) фактически не нуждаются вdata
вызове.Если у вас есть большой набор данных, который не может быть легко помещен в сценарий с помощью
dput()
, отправьте свои данные в pastebin и загрузите их, используяread.table
:Вдохновленный @Henrik .
источник
Я разрабатываю пакет wakefield для решения этой проблемы, чтобы быстро обмениваться воспроизводимыми данными, иногда
dput
отлично работает для небольших наборов данных, но многие проблемы, с которыми мы сталкиваемся, гораздо больше, так как совместное использование такого большого набора данныхdput
нецелесообразно.Около:
wakefield позволяет пользователю обмениваться минимальным кодом для воспроизведения данных. Пользователь устанавливает
n
(количество строк) и задает любое количество предустановленных переменных функций (в настоящее время их 70), которые имитируют реальные данные (такие как пол, возраст, доход и т. Д.)Установка:
В настоящее время (2015-06-11), Wakefield является пакетом GitHub, но в конце концов перейдет в CRAN после написания модульных тестов. Для быстрой установки используйте:
Пример:
Вот пример:
Это производит:
источник
Если
factor
в ваших данных есть одна или несколько переменных, которые вы хотите сделать воспроизводимымиdput(head(mydata))
, рассмотрите возможность добавленияdroplevels
к ним, чтобы уровни факторов, которых нет в минимизированном наборе данных, не были включены в вашиdput
выходные данные, чтобы сделайте пример минимальным :источник
Интересно, может ли ссылка http://old.r-fiddle.org/ быть очень аккуратным способом поделиться проблемой. Он получает уникальный идентификатор типа, и можно даже подумать о встраивании его в SO.
источник
Пожалуйста, не вставляйте выходные данные консоли следующим образом:
Мы не можем скопировать и вставить его напрямую.
Для того, чтобы вопросы и ответы правильно воспроизводимым, попробуйте удалить
+
и ,>
прежде чем отправлять его и положить#
для выходов и комментарии , как это:Еще одна вещь, если вы использовали какую-либо функцию из определенного пакета, упомяните эту библиотеку.
источник
>
и добавляете#
вручную или есть автоматический способ сделать это?>
вручную. Но, для добавления#
, я используюCtrl+Shift+C
ярлык вRStudio
редакторе.Вы можете сделать это с использованием представительства .
Как отметил mt1022 , «... хорошим пакетом для создания минимального воспроизводимого примера является « представ » от tidyverse ».
По словам Тидиверса :
Пример приведен на сайте Tidyverse .
Я думаю, что это самый простой способ создать воспроизводимый пример.
источник
Помимо всех вышеупомянутых ответов, которые я нашел очень интересными, иногда это может быть очень легко, как это обсуждается здесь: - КАК СДЕЛАТЬ МИНИМАЛЬНЫЙ ВОСПРОИЗВОДИМЫЙ ПРИМЕР, ЧТОБЫ ПОЛУЧИТЬ ПОМОЩЬ С R
Есть много способов сделать случайный вектор Создать вектор из 100 чисел со случайными значениями в R, округленными до 2 десятичных знаков или случайной матрицей в R
Обратите внимание, что иногда очень сложно поделиться данными из-за различных причин, таких как размерность и т. Д. Однако все вышеприведенные ответы очень полезны и очень важны для размышления и использования, когда кто-то хочет привести пример воспроизводимых данных. Но учтите, что для того, чтобы сделать данные такими же репрезентативными, как и исходные (в случае, если ОП не может предоставить исходные данные совместно), полезно добавить некоторую информацию в пример данных как (если мы назовем данные mydf1)
Кроме того, нужно знать тип, длину и атрибуты данных, которые могут быть структурами данных.
источник
Вот некоторые из моих предложений:
dput
, чтобы другие могли вам легче помочьinstall.package()
если это действительно необходимо, люди поймут, если вы просто используетеrequire
илиlibrary
Постарайся быть кратким,
Все это является частью воспроизводимого примера.
источник
dput()
было упомянуто ранее, и большая часть этого просто повторяет стандартные рекомендации SO.install.package
функцией, включенной в пример, которая на самом деле не нужна (по моему мнению). Кроме того, использование набора данных R по умолчанию сделает воспроизведение более простым. В руководящих принципах СО ничего конкретно об этих темах не говорится. Кроме того, это было сделано для того, чтобы высказать свое мнение, и именно с этим я столкнулся больше всего.Рекомендуется использовать функции из
testthat
пакета, чтобы показать, что вы ожидаете. Таким образом, другие люди могут изменять ваш код, пока он не запустится без ошибок. Это облегчает бремя тех, кто хотел бы вам помочь, потому что это означает, что им не нужно декодировать ваше текстовое описание. Напримеряснее, чем «Я думаю, что x окажется равным 1,23 для y, равным или превышающим 10, и 3,21 в противном случае, но я не получил ни одного результата». Даже в этом глупом примере, я думаю, код яснее, чем слова. Использование
testthat
позволяет вашему помощнику сосредоточиться на коде, что экономит время, и дает им возможность узнать, что они решили вашу проблему, прежде чем опубликовать ее.источник