Как сделать отличный R воспроизводимый пример

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

Каковы ваши советы по созданию отличного примера? Как вы вставляете структуры данных из r в текстовом формате? Какую еще информацию вы должны включить?

Существуют ли другие трюки в дополнение к использованию dput() , dump() или structure() ? Когда следует включать в себя library() или require() ? Какие зарезервированные слова следует избегать, помимо c , df , data и т. Д.?

Как сделать отличный воспроизводимый пример?

Минимальный воспроизводимый пример состоит из следующих элементов:

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

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

Создание минимального набора данных

В большинстве случаев это можно легко сделать, просто предоставив вектор / фрейм данных с некоторыми значениями. Или вы можете использовать один из встроенных наборов данных, которые предоставляются с большинством пакетов.
Полный список встроенных наборов данных можно увидеть с 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() , например:

 matrix(1:10, ncol = 2) 

Создание кадров данных можно выполнить с помощью data.frame() . Следует обратить внимание на имена записей в кадре данных и не сделать их чрезмерно сложными.

Пример :

 set.seed(1) Data <- data.frame( X = sample(1:10), Y = sample(c("yes", "no"), 10, replace = TRUE) ) 

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

Скопируйте данные

Если у вас есть некоторые данные, которые было бы слишком сложно построить с помощью этих советов, вы всегда можете сделать подмножество исходных данных, используя, например, head() , subset() или индексы. Затем используйте, например. dput() чтобы дать нам что-то, что можно сразу положить в R:

 > dput(head(iris,4)) structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6), Sepal.Width = c(3.5, 3, 3.2, 3.1), Petal.Length = c(1.4, 1.4, 1.3, 1.5), Petal.Width = c(0.2, 0.2, 0.2, 0.2), Species = structure(c(1L, 1L, 1L, 1L), .Label = c("setosa", "versicolor", "virginica"), class = "factor")), .Names = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"), row.names = c(NA, 4L), class = "data.frame") 

Если ваш фрейм данных имеет коэффициент со многими уровнями, выход dput может быть громоздким, поскольку он все равно будет перечислять все возможные уровни факторов, даже если они не присутствуют в подмножестве ваших данных. Чтобы решить эту проблему, вы можете использовать droplevels() . Ниже следует, как вид является фактором только с одним уровнем:

 > dput(droplevels(head(iris, 4))) structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6), Sepal.Width = c(3.5, 3, 3.2, 3.1), Petal.Length = c(1.4, 1.4, 1.3, 1.5), Petal.Width = c(0.2, 0.2, 0.2, 0.2), Species = structure(c(1L, 1L, 1L, 1L), .Label = "setosa", class = "factor")), .Names = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"), row.names = c(NA, 4L), class = "data.frame") 

Еще одна оговорка для dput заключается в том, что она не будет работать для ключевых данных. data.table объекты или для группировки tbl_df (class grouped_df ) из dplyr . В этих случаях вы можете конвертировать обратно в обычный кадр данных до совместного использования, dput(as.data.frame(my_data)) .

В худшем случае вы можете дать текстовое представление, которое можно прочитать при использовании text параметра read.table :

 zz <- "Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa" Data <- read.table(text=zz, header = TRUE) 

Создание минимального кода

Это должно быть легкой частью, но часто это не так. То, что вы не должны делать, это:

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

Что вы должны делать, это:

  • добавьте, какие пакеты следует использовать, если вы используете их (используя library() )
  • если вы открываете соединения или создаете файлы, добавляете какой-то код, чтобы закрыть их или удалить файлы (используя unlink() )
  • если вы измените параметры, убедитесь, что код содержит инструкцию, чтобы вернуть их обратно к исходным. (например, op <- par(mfrow=c(1,2)) ...some code... par(op) )
  • проверите свой код в новом, пустом сеансе R, чтобы убедиться, что код запущен. Люди должны иметь возможность просто скопировать ваши данные и ваш код в консоли и получить то же самое, что и у вас.

Предоставьте дополнительную информацию

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

Если вы используете R в R Studio, используя rstudioapi::versionInfo() может быть полезно сообщить о вашей версии RStudio.

Если у вас возникла проблема с конкретным пакетом, вы можете предоставить версию пакета, предоставив результат packageVersion("name of the package") .

(Вот мой совет: Как написать воспроизводимый пример . Я пытался сделать его коротким, но сладким)

Как написать воспроизводимый пример.

Вы, скорее всего, получите хорошую помощь с вашей проблемой R, если вы предоставите воспроизводимый пример. Воспроизводимый пример позволяет кому-то еще воссоздать вашу проблему, просто скопировав и вставив R-код.

Вам необходимо включить четыре варианта, чтобы сделать ваш пример воспроизводимым: требуемые пакеты, данные, код и описание вашей среды R.

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

  • Самый простой способ включить данные в сообщение электронной почты или вопрос переполнения стека – использовать dput() для генерации кода R для его воссоздания. Например, чтобы воссоздать dataset mtcars в R, я бы выполнил следующие шаги:

    1. Запуск dput(mtcars) в R
    2. Скопируйте вывод
    3. В моем воспроизводимом скрипте введите mtcars <- then paste.
  • Потратьте немного времени на то, чтобы ваш код легко читал другим:

    • убедитесь, что вы использовали пробелы, а имена переменных краткие, но информативные

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

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

  • Включите вывод sessionInfo() в комментарии в коде. Это суммирует вашу среду R и позволяет легко проверить, используете ли вы устаревший пакет.

Вы можете проверить, что вы действительно сделали воспроизводимый пример, запустив новый сеанс R и вставив свой скрипт.

Прежде чем поместить весь свой код в электронное письмо, подумайте о том, чтобы положить его в Gist github . Это придаст вашему коду приятный синтаксический подсветка, и вам не придется беспокоиться о чем-либо, искаженном системой электронной почты.

Лично я предпочитаю «один» лайнер. Что-то вроде строк:

 my.df <- data.frame(col1 = sample(c(1,2), 10, replace = TRUE), col2 = as.factor(sample(10)), col3 = letters[1:10], col4 = sample(c(TRUE, FALSE), 10, replace = TRUE)) my.list <- list(list1 = my.df, list2 = my.df[3], list3 = letters) 

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

В качестве альтернативы можно было бы сократить несколько углов и указать на уже существующий dataset, например:

 library(vegan) data(varespec) ord <- metaMDS(varespec) 

Не забудьте указать какие-либо специальные пакеты, которые вы могли бы использовать.

Если вы пытаетесь продемонстрировать что-то на более крупных объектах, вы можете попробовать

 my.df2 <- data.frame(a = sample(10e6), b = sample(letters, 10e6, replace = TRUE)) 

Если вы работаете с пространственными данными через raster пакет, вы можете сгенерировать некоторые случайные данные. Много примеров можно найти в виньетике пакета, но вот небольшой самородок.

 library(raster) r1 <- r2 <- r3 <- raster(nrow=10, ncol=10) values(r1) <- runif(ncell(r1)) values(r2) <- runif(ncell(r2)) values(r3) <- runif(ncell(r3)) s <- stack(r1, r2, r3) 

Если вам нужен какой-либо пространственный объект, реализованный в sp , вы можете получить некоторые наборы данных через внешние файлы (например, шейп-файл ESRI) в «пространственных» пакетах (см. Пространственный вид в представлении задач).

 library(rgdal) ogrDrivers() dsn <- system.file("vectors", package = "rgdal")[1] ogrListLayers(dsn) ogrInfo(dsn=dsn, layer="cities") cities <- readOGR(dsn=dsn, layer="cities") 

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


БЫСТРЫЕ ИНСТРУКЦИИ

Если myData – это имя вашего объекта для воспроизведения, запустите в R:

 install.packages("devtools") library(devtools) source_url("https://raw.github.com/rsaporta/pubR/gitbranch/reproduce.R") reproduce(myData) 

Детали:

Эта функция является интеллектуальной оболочкой для dput и выполняет следующие действия:

  • автоматически формирует большой dataset (в зависимости от размера и classа. Размер выборки может быть скорректирован)
  • создает dput мощность
  • позволяет указать, какие столбцы экспортировать
  • добавляет перед ним objName <- ... так что его можно легко скопировать + вставить, но ...
  • Если вы работаете на Mac, вывод автоматически копируется в буфер обмена, так что вы можете просто запустить его, а затем вставить в свой вопрос.

Источник доступен здесь:

  • Github - pubR / воспроизведение.R

Пример:

 # sample data DF <- data.frame(id=rep(LETTERS, each=4)[1:100], replicate(100, sample(1001, 100)), Class=sample(c("Yes", "No"), 100, TRUE)) 

DF составляет около 100 x 102. Я хочу пробовать 10 строк и несколько конкретных столбцов

 reproduce(DF, cols=c("id", "X1", "X73", "Class")) # I could also specify the column number. 

Дает следующий результат:

 This is what the sample looks like: id X1 X73 Class 1 A 266 960 Yes 2 A 373 315 No Notice the selection split 3 A 573 208 No (which can be turned off) 4 A 907 850 Yes 5 B 202 46 Yes 6 B 895 969 Yes <~~~ 70 % of selection is from the top rows 7 B 940 928 No 98 Y 371 171 Yes 99 Y 733 364 Yes <~~~ 30 % of selection is from the bottom rows. 100 Y 546 641 No ==X==============================================================X== Copy+Paste this part. (If on a Mac, it is already copied!) ==X==============================================================X== DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L, 25L, 25L), .Label = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"), class = "factor"), X1 = c(266L, 373L, 573L, 907L, 202L, 895L, 940L, 371L, 733L, 546L), X73 = c(960L, 315L, 208L, 850L, 46L, 969L, 928L, 171L, 364L, 641L), Class = structure(c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L), .Label = c("No", "Yes"), class = "factor")), .Names = c("id", "X1", "X73", "Class"), class = "data.frame", row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L)) ==X==============================================================X== 

Также обратите внимание, что весь вывод находится в хорошей одиночной, длинной строке, а не в высоком абзаце нарезанных строк. Это облегчает чтение сообщений на SO-сообщениях, а также проще скопировать + вставить.


Обновление октябрь 2013:

Теперь вы можете указать, сколько строк текстового вывода будет занимать (то есть, что вы будете вставлять в StackOverflow). Для этого используйте аргумент lines.out=n . Пример:

reproduce(DF, cols=c(1:3, 17, 23), lines.out=7) дает:

  ==X==============================================================X== Copy+Paste this part. (If on a Mac, it is already copied!) ==X==============================================================X== DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L,25L, 25L), .Label = c("A", "B", "C", "D", "E", "F", "G", "H","I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U","V", "W", "X", "Y"), class = "factor"), X1 = c(809L, 81L, 862L,747L, 224L, 721L, 310L, 53L, 853L, 642L), X2 = c(926L, 409L,825L, 702L, 803L, 63L, 319L, 941L, 598L, 830L), X16 = c(447L,164L, 8L, 775L, 471L, 196L, 30L, 420L, 47L, 327L), X22 = c(335L,164L, 503L, 407L, 662L, 139L, 111L, 721L, 340L, 178L)), .Names = c("id","X1", "X2", "X16", "X22"), class = "data.frame", row.names = c(1L,2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L)) ==X==============================================================X== 

Вот хорошее руководство:

http://www.r-bloggers.com/three-tips-for-posting-good-questions-to-r-help-and-stack-overflow/

Но самое главное: просто убедитесь, что вы создаете небольшой fragment кода, который мы можем запустить, чтобы посмотреть, в чем проблема. Полезной функцией для этого является dput() , но если у вас очень большие данные, вы можете захотеть создать небольшой dataset образца или использовать только первые 10 строк или около того.

РЕДАКТИРОВАТЬ:

Также убедитесь, что вы определили, где проблема сама. В этом примере не должен быть весь R-скрипт с «В строке 200 есть ошибка». Если вы используете инструменты отладки в R (я люблю browser() ) и google, вы должны быть в состоянии действительно определить, где проблема, и воспроизвести тривиальный пример, в котором то же самое происходит неправильно.

В списке рассылки R-help есть руководство по проводке, которое охватывает как вопросы, так и ответы на вопросы, в том числе пример создания данных:

Примеры. Иногда это помогает предоставить небольшой пример того, что кто-то действительно может работать. Например:

Если у меня есть matrix х следующим образом:

  > x <- matrix(1:8, nrow=4, ncol=2, dimnames=list(c("A","B","C","D"), c("x","y")) > x xy A 1 5 B 2 6 C 3 7 D 4 8 > 

как я могу превратить его в кадр данных с 8 строками и тремя столбцами с именем «строка», «кол» и «значение», которые имеют имена размеров как значения «row» и «col», например:

  > x.df row col value 1 A x 1 


(Ответ на который может быть следующим:

  > x.df <- reshape(data.frame(row=rownames(x), x), direction="long", varying=list(colnames(x)), times=colnames(x), v.names="value", timevar="col", idvar="row") 

)

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

EDIT: Довольно легко читать код, чем уродливый код. Используйте руководство по стилю .

Так как R.2.14 (я думаю), вы можете напрямую подать свое текстовое представление в read.table:

 df <- read.table(header=T, text="Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa ") 

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

  • Возможно, потребуется отправить данные в Интернет и предоставить URL-адрес.
  • Если данные не могут быть выпущены широкой публике, но могут быть вообще доступны, вы можете предложить отправить по электронной почте заинтересованным сторонам (хотя это сократит количество людей, которые будут работать на работу в теме).
  • Я на самом деле не видел этого, потому что люди, которые не могут выпускать свои данные, чувствительны к выпуску любой формы, но было бы правдоподобно, что в некоторых случаях все еще можно было бы отправлять данные, если бы они были достаточно анонимными / скремблированными / искаженными каким-то образом.

Если вы не можете сделать ни одно из них, вам, вероятно, потребуется нанять консультанта для решения вашей проблемы …

edit : Два полезных вопроса SO для анонимности / скремблирования:

  • Как создать пример данных из частных данных (заменяя имена переменных и уровни владельцами неинформативных мест)?
  • Учитывая набор случайных чисел, взятых из непрерывного одномерного распределения, найдем распределение

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

Вот воспроизводимый пример того, чего следует избегать (из реального примера, имена изменены для защиты невинных):


Ниже приведены примеры данных и часть функции, с которой я столкнулся.

 code code code code code (40 or so lines of it) 

Как я могу это достичь?


Чтобы быстро создать dput данных, вы можете просто скопировать (часть) данных в буфер обмена и запустить в R:

для данных в Excel:

 dput(read.table("clipboard",sep="\t",header=TRUE)) 

для данных в txt-файле:

 dput(read.table("clipboard",sep="",header=TRUE)) 

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

У меня очень простой и эффективный способ сделать пример R, который не упоминался выше. Сначала вы можете определить свою структуру. Например,

 mydata <- data.frame(a=character(0), b=numeric(0), c=numeric(0), d=numeric(0)) >fix(mydata) 

Когда вы выполняете команду «fix», вы получите это всплывающее окно

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

Методические рекомендации:


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

  1. Предоставление входных данных
  2. Обеспечить ожидаемый результат
  3. Объясните свою проблему лаконично
    • если у вас более 20 строк текста + код, вы, вероятно, можете вернуться и упростить
    • упростите свой код как можно больше, сохраняя проблему / ошибку

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

Предоставление данных:


Встроенные наборы данных

Лучший вариант – это полагаться на встроенные наборы данных. Это облегчает для других работу над вашей проблемой. Введите data() в приглашении R, чтобы узнать, какие данные доступны для вас. Некоторые classические примеры:

  • iris
  • mtcars
  • ggplot2::diamonds (внешний пакет, но почти у всех есть)

См. Этот SO Q для поиска наборов данных, подходящих для вашей проблемы.

Если вы можете перефразировать свою проблему, чтобы использовать встроенные наборы данных, вы, скорее всего, получите хорошие ответы (и upvotes).

Самогенерированные данные

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

 set.seed(1) # important to make random data reproducible myData <- data.frame(a=sample(letters[1:5], 20, rep=T), b=runif(20)) 

Теперь кто-то, кто пытается ответить на мой вопрос, может скопировать / вставить эти две строки и немедленно начать работу над проблемой.

dput

В крайнем случае вы можете использовать dput для преобразования объекта данных в R-код (например, dput(myData) ). Я говорю как «последнее средство», потому что выход dput часто довольно громоздкий, раздражающий для копирования-вставки и скрывает остальную часть вашего вопроса.

Обеспечить ожидаемый результат:


Кто-то однажды сказал:

Изображение ожидаемого результата стоит 1000 слов

- очень мудрый человек

Если вы можете добавить что-то вроде «Я ожидал получить этот результат»:

  cyl mean.hp 1: 6 122.28571 2: 4 82.63636 3: 8 209.21429 

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

Объясните свою проблему кратко


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

Вот несколько примеров хороших вопросов:

  • со встроенным набором данных
  • с данными пользователя

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

Почему еще один ответ на этот вопрос?


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

Воспроизводимый код является ключом для получения справки. Однако есть много пользователей, которые могут скептически относиться к вставке даже части их данных. Например, они могут работать с конфиденциальными данными или с исходными данными, собранными для использования в исследовательском документе. По какой-то причине я подумал, что было бы неплохо иметь удобную функцию для «деформирования» моих данных, прежде чем публиковать ее. Функция anonymize из пакета dput очень глупа, но для меня она отлично работает с функцией dput .

 install.packages("SciencesPo") dt <- data.frame( Z = sample(LETTERS,10), X = sample(1:10), Y = sample(c("yes", "no"), 10, replace = TRUE) ) > dt ZXY 1 D 8 no 2 T 1 yes 3 J 7 no 4 K 6 no 5 U 2 no 6 A 10 yes 7 Y 5 no 8 M 9 yes 9 X 4 yes 10 Z 3 no 

Затем я анонимизирую его:

 > anonymize(dt) ZXY 1 b2 2.5 c1 2 b6 -4.5 c2 3 b3 1.5 c1 4 b4 0.5 c1 5 b7 -3.5 c1 6 b1 4.5 c2 7 b9 -0.5 c1 8 b5 3.5 c2 9 b8 -1.5 c2 10 b10 -2.5 c1 

Также может потребоваться выборка нескольких переменных вместо всех данных перед применением команды anonymization и dput.

  # sample two variables without replacement > anonymize(sample.df(dt,5,vars=c("Y","X"))) YX 1 a1 -0.4 2 a1 0.6 3 a2 -2.4 4 a1 -1.4 5 a2 3.6 

Часто вам нужны некоторые данные для примера, однако вы не хотите публиковать свои точные данные. Чтобы использовать некоторые существующие data.frame в установленной библиотеке, используйте команду data для ее импорта.

например,

 data(mtcars) 

и затем выполните задачу

 names(mtcars) your problem demostrated on the mtcars data set 

Если у вас есть большой dataset, который нельзя легко поместить в скрипт с помощью dput() , dput() свои данные в pastebin и загрузите их, используя read.table :

 d <- read.table("http://pastebin.com/raw.php?i=m1ZJuKLH") 

Вдохновленный @ Хенрик .

Я разрабатываю пакет wakefield для решения этой проблемы, чтобы быстро делиться воспроизводимыми данными, иногда dput отлично работает для небольших наборов данных, но многие из проблем, с которыми мы имеем дело, намного больше, использование такого большого набора данных через dput нецелесообразно.

Около:

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

Монтаж:

В настоящее время (2015-06-11), wakefield является пакетом GitHub, но будет отправляться в CRAN в конце концов после написания модульных тестов. Для быстрой установки используйте:

 if (!require("pacman")) install.packages("pacman") pacman::p_load_gh("trinker/wakefield") 

Пример:

Вот пример:

 r_data_frame( n = 500, id, race, age, sex, hour, iq, height, died ) 

Это дает:

  ID Race Age Sex Hour IQ Height Died 1 001 White 33 Male 00:00:00 104 74 TRUE 2 002 White 24 Male 00:00:00 78 69 FALSE 3 003 Asian 34 Female 00:00:00 113 66 TRUE 4 004 White 22 Male 00:00:00 124 73 TRUE 5 005 White 25 Female 00:00:00 95 72 TRUE 6 006 White 26 Female 00:00:00 104 69 TRUE 7 007 Black 30 Female 00:00:00 111 71 FALSE 8 008 Black 29 Female 00:00:00 100 64 TRUE 9 009 Asian 25 Male 00:30:00 106 70 FALSE 10 010 White 27 Male 00:30:00 121 68 FALSE .. ... ... ... ... ... ... ... ... 

Если у вас есть одна или несколько переменных (-ов) factor в ваших данных, которые вы хотите воспроизвести с помощью dput(head(mydata)) , подумайте о добавлении к нему droplevels , чтобы уровни факторов, которых нет в свернутом наборе данных, не включенный в ваш выход dput , чтобы сделать пример минимальным :

 dput(droplevels(head(mydata))) 

Интересно, может ли ссылка http://www.r-fiddle.org/ быть очень аккуратным способом совместного использования проблемы. Он получает уникальный идентификатор, и даже можно подумать о его внедрении в SO.

http://www.r-fiddle.org/#/help

Не вставляйте консольные выходы следующим образом:

 If I have a matrix x as follows: > x <- matrix(1:8, nrow=4, ncol=2, dimnames=list(c("A","B","C","D"), c("x","y"))) > x xy A 1 5 B 2 6 C 3 7 D 4 8 > How can I turn it into a dataframe with 8 rows, and three columns named `row`, `col`, and `value`, which have the dimension names as the values of `row` and `col`, like this: > x.df row col value 1 A x 1 ... (To which the answer might be: > x.df <- reshape(data.frame(row=rownames(x), x), direction="long", + varying=list(colnames(x)), times=colnames(x), + v.names="value", timevar="col", idvar="row") ) 

We can not copy-paste it directly.

To make questions and answers properly reproducible, try to remove + & > before posting it and put # for outputs and comments like this:

 #If I have a matrix x as follows: x <- matrix(1:8, nrow=4, ncol=2, dimnames=list(c("A","B","C","D"), c("x","y"))) x # xy #A 1 5 #B 2 6 #C 3 7 #D 4 8 # How can I turn it into a dataframe with 8 rows, and three # columns named `row`, `col`, and `value`, which have the # dimension names as the values of `row` and `col`, like this: #x.df # row col value #1 A x 1 #... #To which the answer might be: x.df <- reshape(data.frame(row=rownames(x), x), direction="long", varying=list(colnames(x)), times=colnames(x), v.names="value", timevar="col", idvar="row") 

One more thing, if you have used any function from certain package, mention that library.

Apart of all above answers which I found very interesting, it could sometimes be very easy as it is discussed here :- HOW TO MAKE A MINIMAL REPRODUCIBLE EXAMPLE TO GET HELP WITH R

There are many ways to make a random vector Create a 100 number vector with random values in R rounded to 2 decimals or random matrix in R

 mydf1<- matrix(rnorm(20),nrow=20,ncol=5) 

Note that sometimes it is very difficult to share a given data because of various reasons such as dimension etc. However, all above answers are great and very important to think and use when one wants to make a reproducible data example. But note that in order to make a data as representative as the original (in case the OP cannot share the original data), it is good to add some information with the data example as (if we call the data mydf1)

 class(mydf1) # this shows the type of the data you have dim(mydf1) # this shows the dimension of your data 

Moreover, one should know the type, length and attributes of a data which can be Data structures

 #found based on the following typeof(mydf1), what it is. length(mydf1), how many elements it contains. attributes(mydf1), additional arbitrary metadata. #If you cannot share your original data, you can str it and give an idea about the structure of your data head(str(mydf1)) 

Here are some of my suggestions:

  • Try to use default R datasets
  • If you have your own dataset, include them with dput , so others can help you more easily
  • Do not use install.package() unless it is really necessary, people will understand if you just use require or library
  • Try to be concise,

    • Have some dataset
    • Try to describe the output you need as simply as possible
    • Do it yourself before you ask the question
  • It is easy to upload an image, so upload plots if you have
  • Also include any errors you may have

All these are part of a reproducible example.

You can do this using reprex .

As mt1022 noted , “… good package for producing minimal, reproducible example is “reprex” from tidyverse “.

According to Tidyverse :

The goal of “reprex” is to package your problematic code in such a way that other people can run it and feel your pain.

An example is given on tidyverse web site.

 library(reprex) y <- 1:4 mean(y) reprex() 

I think this is the simplest way to create a reproducible example.

It’s a good idea to use functions from the testthat package to show what you expect to occur. Thus, other people can alter your code until it runs without error. This eases the burden of those who would like to help you, because it means they don’t have to decode your textual description. Например

 library(testthat) # code defining x and y if (y >= 10) { expect_equal(x, 1.23) } else { expect_equal(x, 3.21) } 

is clearer than “I think x would come out to be 1.23 for y equal to or exceeding 10, and 3.21 otherwise, but I got neither result”. Even in this silly example, I think the code is clearer than the words. Using testthat lets your helper focus on the code, which saves time, and it provides a way for them to know they have solved your problem, before they post it

  • Rscript: определение пути исполняемого скрипта
  • Элегантный способ проверить недостающие пакеты и установить их?
  • Установка кривой плотности на гистограмму в R
  • Числовая сложность сравнения в R
  • Добавление начальных нhive с использованием R
  • Как эффективно фильтровать фрейм данных?
  • Постройте два графика в одном графике в R
  • Объедините два кадра данных по строкам (rbind), когда они имеют разные наборы столбцов
  • Использовать имена переменных в функциях dplyr
  • Оценить выражение, данное как строка
  • Участок с осью 2 y, одна ось y слева и другая ось y справа
  • Давайте будем гением компьютера.