etc./StackOverFlow

훌륭한 R 재현 가능한 예제를 만드는 방법

청렴결백한 만능 재주꾼 2021. 11. 23. 03:44
반응형

질문자 :Community Wiki


동료와 성과에 대해 논의하거나, 버그 보고서를 보내거나, 메일링 리스트 및 여기 Stack Overflow에서 지침을 검색할 때 재현 가능한 예제 가 자주 요청되고 항상 도움이 됩니다.

훌륭한 예를 만들기 위한 팁은 무엇입니까? 데이터 구조를 텍스트 형식으로 어떻게 붙여넣나요? 어떤 다른 정보를 포함해야 합니까?

dput() , dump() 또는 structure() 사용 외에 다른 트릭이 있습니까? library() 또는 require() 문을 포함해야 합니까? c , df , data 등 외에 어떤 예약어를 피해야 합니까?

어떻게 훌륭한 재현 가능한 예를 만들 수 있습니까?



기본적으로 MRE(Minimal Reproducible Example) 는 다른 사람들이 자신의 컴퓨터에서 문제 를 정확하게 재현할 수 있도록 해야 합니다.

MRE는 다음 항목으로 구성됩니다.

  • 문제를 입증하는 데 필요한 최소한의 데이터 세트
  • 주어진 데이터 세트에서 실행할 수 있는 오류를 재현하는 데 필요한 최소한의 실행 가능한 코드
  • 사용된 패키지, R 버전 및 실행되는 OS에 대한 모든 필요한 정보.
  • 무작위 프로세스의 경우 재현성을 위해 시드 ( set.seed()

좋은 MRE의 예는 사용 중인 기능에 대한 도움말 파일 하단의 "예제" 섹션을 참조하십시오. 예를 들어 help(mean) 또는 짧은 ?mean 을 R 콘솔에 입력하기만 하면 됩니다.

최소한의 데이터 세트 제공

일반적으로 거대한 데이터 세트를 공유하는 것은 필요하지 않으며 오히려 다른 사람들이 귀하의 질문을 읽는 것을 방해할 수 있습니다. 따라서 기본 제공 데이터 세트를 사용하거나 원래 데이터와 유사한 작은 "장난감" 예제를 만드는 것이 좋습니다. 이는 실제로 최소 가 의미하는 것입니다. 어떤 이유로 원본 데이터를 공유해야 하는 경우 다른 사람이 데이터의 정확한 복사본을 얻을 수 있도록 하는 dput()

내장 데이터세트

기본 제공 데이터 세트 중 하나를 사용할 수 있습니다. 내장 데이터 세트의 포괄적인 목록은 data() 로 볼 수 있습니다. 모든 데이터 세트에 대한 간략한 설명이 있으며, 예를 들어 R과 함께 제공되는 'iris' 데이터 세트에 대해 ?iris

예시 데이터 세트 생성

예비 참고 사항: 때로는 요인, 날짜 또는 시계열과 같은 특수 형식(예: 클래스)이 필요할 수 있습니다. as.factor , as.Date , as.xts , ... 같은 기능을 사용하십시오 . 예:

 d <- as.Date("2020-12-30")

어디

 class(d) # [1] "Date"

벡터

 x <- rnorm(10) ## random vector normal distributed x <- runif(10) ## random vector uniformly distributed x <- sample(1:100, 10) ## 10 random draws out of 1, 2, ..., 100 x <- sample(LETTERS, 10) ## 10 random draws out of built-in latin alphabet

행렬

 m <- matrix(1:12, 3, 4, dimnames=list(LETTERS[1:3], LETTERS[1:4])) m # ABCD # A 1 4 7 10 # B 2 5 8 11 # C 3 6 9 12

데이터 프레임

 set.seed(42) ## for sake of reproducibility n <- 6 dat <- data.frame(id=1:n, date=seq.Date(as.Date("2020-12-26"), as.Date("2020-12-31"), "day"), group=rep(LETTERS[1:2], n/2), age=sample(18:30, n, replace=TRUE), type=factor(paste("type", 1:n)), x=rnorm(n)) dat # id date group age type x # 1 1 2020-12-26 A 27 type 1 0.0356312 # 2 2 2020-12-27 B 19 type 2 1.3149588 # 3 3 2020-12-28 A 20 type 3 0.9781675 # 4 4 2020-12-29 B 26 type 4 0.8817912 # 5 5 2020-12-30 A 26 type 5 0.4822047 # 6 6 2020-12-31 B 28 type 6 0.9657529

참고: 널리 사용되지만 데이터 프레임의 이름을 df df() 는 F 분포의 밀도(즉, 점 x 에서의 곡선 높이)에 대한 R 함수이고 충돌할 수 있기 때문입니다. .

원본 데이터 복사

dput 을 사용하여 원본 데이터의 작은 하위 집합을 제공하는 것이 가장 좋습니다.

dput() 사용하는 이유는 무엇입니까?

dput 은 콘솔에서 데이터를 정확하게 재생하는 데 필요한 모든 정보를 표시합니다. 출력을 복사하여 질문에 붙여넣기만 하면 됩니다.

dat (위에서)를 호출하면 질문에서 공유하는 경우 변수 클래스 및 기타 기능에 대한 정보가 여전히 부족한 출력이 생성됩니다. type 열의 공백으로 인해 아무 작업도 수행하기 어렵습니다. 데이터를 사용하기 시작하더라도 데이터의 중요한 기능을 제대로 사용하지 못할 것입니다.

 id date group age type x 1 1 2020-12-26 A 27 type 1 0.0356312 2 2 2020-12-27 B 19 type 2 1.3149588 3 3 2020-12-28 A 20 type 3 0.9781675

데이터의 하위 집합

하위 집합을 공유하려면 head() , subset() 또는 인덱스 iris[1:4, ] . 그런 다음 R에 즉시 넣을 수 있는 무언가를 다른 사람에게 제공하기 위해 dput() 으로 래핑합니다. 예시

 dput(iris[1:4, ]) # first four rows of the iris data set

귀하의 질문에 공유할 콘솔 출력:

 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")), row.names = c(NA, 4L), class = "data.frame")

dput 사용할 때 관련 열만 포함할 수도 있습니다(예: dput(mtcars[1:3, c(2, 5, 6)])

참고: 데이터 프레임에 수준이 많은 요인이 있는 경우 dput 출력은 데이터의 하위 집합에 없는 경우에도 가능한 모든 요인 수준을 계속 나열하므로 다루기 어려울 수 있습니다. 이 문제를 해결하려면 droplevels() 함수를 사용할 수 있습니다. dput(droplevels(iris[1:4, ])) 과 같이 한 수준만 있는 요소인 방법에 주목하세요. 한 가지 다른주의 dput 이 키 입력을 위해 작동하지 않을 것입니다 data.table 개체 또는 그룹화에 대한 tbl_df (클래스 grouped_df 로부터) tidyverse . dput(as.data.frame(my_data)) 공유하기 전에 일반 데이터 프레임으로 다시 변환할 수 있습니다.

최소한의 코드 생성

최소한의 데이터(위 참조)와 결합하여 코드는 단순히 복사하여 붙여넣기만 하면 다른 시스템에서 문제를 정확하게 재현해야 합니다.

이것은 쉬운 부분이어야 하지만 종종 그렇지 않습니다. 하지 말아야 할 것:

  • 모든 종류의 데이터 변환을 보여줍니다. 제공된 데이터가 이미 올바른 형식인지 확인하십시오(물론 문제가 아닌 경우).
  • 어딘가에 오류가 발생하는 전체 스크립트를 복사하여 붙여넣습니다. 정확히 어떤 줄에서 오류가 발생했는지 찾아보십시오. 대부분의 경우 문제가 자신에게 무엇인지 알게 될 것입니다.

해야 할 일:

  • 사용하는 패키지를 추가하십시오( library() ).
  • 새로운 R 세션에서 코드를 테스트 실행하여 코드를 실행할 수 있는지 확인하십시오. 사람들은 콘솔에 데이터와 코드를 복사하여 붙여넣고 동일한 것을 얻을 수 있어야 합니다.
  • 연결을 열거나 파일을 생성하는 경우 일부 코드를 추가하여 unlink() )
  • 옵션을 변경하는 경우 코드에 원래 옵션으로 되돌리는 명령문이 포함되어 있는지 확인하십시오. (예: op <- par(mfrow=c(1,2)) ...some code... par(op) )

필요한 정보 제공

대부분의 경우 R 버전과 운영 체제만 있으면 충분합니다. 패키지와 충돌이 발생할 때 sessionInfo() 의 출력을 제공하면 정말 도움이 될 수 있습니다. 다른 응용 프로그램(ODBC 또는 기타를 통한 연결)에 대한 연결에 대해 이야기할 때 해당 응용 프로그램에 대한 버전 번호도 제공해야 하며 가능한 경우 설정에 필요한 정보도 제공해야 합니다.

R Studio 에서 R을 실행하는 경우 rstudioapi::versionInfo() 를 사용하면 RStudio 버전을 보고하는 데 도움이 될 수 있습니다.

packageVersion("name of the package") 의 출력을 제공하여 패키지 버전을 제공할 수 있습니다.

씨앗

set.seed() 를 사용하여 시드 1을 지정할 수 있습니다. 즉, 특정 상태, R의 난수 생성기가 고정되어 있습니다. sample() , rnorm() , runif() 및 기타 많은 함수와 같은 임의의 함수가 항상 동일한 결과를 반환할 수 있습니다. 예:

 set.seed(42) rnorm(3) # [1] 1.3709584 -0.5646982 0.3631284 set.seed(42) rnorm(3) # [1] 1.3709584 -0.5646982 0.3631284

1 참고: set.seed() 의 출력은 R >3.6.0과 이전 버전 간에 다릅니다. 임의 프로세스에 사용한 R 버전을 지정하고 오래된 질문을 따를 때 약간 다른 결과가 나온다고 놀라지 마십시오. 이러한 경우에 동일한 결과를 얻으려면 RNGversion() 전에 set.seed() 사용할 수 있습니다(예: RNGversion("3.5.2") ).


Community Wiki

(여기서 How to write a reproducible example 에서 내 조언이 있습니다. 짧지 만 달콤하게 만들려고 노력했습니다).

재현 가능한 예제를 작성하는 방법

재현 가능한 예를 제공하면 R 문제에 대해 좋은 도움을 받을 가능성이 가장 큽니다. 재현 가능한 예제를 사용하면 R 코드를 복사하여 붙여넣기만 하면 다른 사람이 문제를 재현할 수 있습니다.

예제를 재현 가능하게 하려면 필수 패키지, 데이터, 코드 및 R 환경에 대한 설명의 네 가지를 포함해야 합니다.

  • 패키지 는 스크립트 맨 위에 로드되어야 하므로 예제에 필요한 패키지를 쉽게 확인할 수 있습니다.

  • 이메일 또는 스택 오버플로 질문에 데이터 를 포함하는 가장 쉬운 방법 dput() 을 사용하여 R 코드를 생성하여 다시 만드는 것입니다. 예를 들어 mtcars 데이터 세트를 다시 생성하려면 다음 단계를 수행합니다.

    1. R에서 dput(mtcars) 실행
    2. 출력 복사
    3. 재현 가능한 스크립트에서 mtcars <- 를 입력한 다음 붙여넣습니다.
  • 다른 사람들이 쉽게 읽을 수 있도록 코드를 작성 하는 데 약간의 시간을 할애하십시오.

    • 공백을 사용하고 변수 이름이 간결하지만 정보를 제공하는지 확인하십시오.

    • 주석을 사용하여 문제가 있는 위치를 나타냅니다.

    • 문제와 관련되지 않은 모든 것을 제거하기 위해 최선을 다하십시오.
      코드가 짧을수록 이해하기 쉽습니다.

  • 코드의 주석에 sessionInfo() 의 출력을 포함합니다. 이것은 R 환경을 요약하고 오래된 패키지를 사용하고 있는지 쉽게 확인할 수 있도록 합니다.

새로운 R 세션을 시작하고 스크립트를 붙여넣어 실제로 재현 가능한 예제를 만들었는지 확인할 수 있습니다.

모든 코드를 이메일에 넣기 전에 Gist github 에 넣는 것을 고려하십시오. 코드에 멋진 구문 강조 표시가 제공되며 이메일 시스템에 의해 엉망이 되는 것에 대해 걱정할 필요가 없습니다.


Community Wiki

개인적으로 나는 "하나" 라이너를 선호합니다. 라인을 따라 뭔가 :

 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 와 같은)를 덮어쓰지 않을 때 정말 감사합니다.

또는 다음과 같이 모서리 몇 개를 잘라내고 기존 데이터 세트를 가리킬 수 있습니다.

 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 에서 구현된 공간 개체가 필요한 경우 "spatial" 패키지의 외부 파일(예: ESRI shapefile)을 통해 일부 데이터세트를 얻을 수 있습니다(작업 보기의 공간 보기 참조).

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

Community Wiki

바로 이 게시물에서 영감을 받아 스택 오버플로에 게시해야 할 때 reproduce(<mydata>)


빠른 지침

myData 가 재현할 개체의 이름인 경우 R에서 다음을 실행합니다.

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

세부:

이 함수는 dput 대한 지능형 래퍼이며 다음을 수행합니다.

  • 대규모 데이터 세트 자동 샘플링(크기 및 클래스 기반. 샘플 크기 조정 가능)
  • dput 출력을 생성합니다.
  • 내보낼 열을 지정할 수 있습니다.
  • objName <- ... 앞에 추가하여 쉽게 복사하여 붙여넣을 수 있지만...
  • Mac에서 작업하는 경우 출력이 클립보드에 자동으로 복사되므로 간단히 실행한 다음 질문에 붙여넣을 수 있습니다.

소스는 다음에서 사용할 수 있습니다.


예시:

 # 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==

또한 출력 전체가 잘린 줄로 된 긴 단락이 아니라 멋진 단일 긴 줄에 있음에 유의하십시오. 이렇게 하면 스택 오버플로 질문 게시물을 더 쉽게 읽을 수 있고 복사+붙여넣기도 더 쉽게 할 수 있습니다.


2013년 10월 업데이트:

이제 텍스트 출력의 줄 수를 지정할 수 있습니다(즉, 스택 오버플로에 붙여넣을 내용). 이를 위해 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==

Community Wiki

여기 좋은 가이드가 있습니다.

가장 중요한 점은 다음과 같습니다. 문제가 무엇인지 보기 위해 실행할 수 있는 작은 코드 조각을 만드십시오. 이에 유용한 함수는 dput() 이지만 데이터가 매우 큰 경우 작은 샘플 데이터 세트를 만들거나 처음 10줄 정도만 사용할 수 있습니다.

편집하다:

또한 문제가 어디에 있는지 식별했는지 확인하십시오. 예제는 "On line 200 there is a error"가 있는 전체 R 스크립트가 아니어야 합니다. browser() ) 및 Google에서 디버깅 도구를 사용하는 경우 문제가 어디에 있는지 실제로 식별하고 동일한 문제가 발생하는 사소한 예를 재현할 수 있어야 합니다.


Community Wiki

R-help 메일링 리스트에는 데이터 생성 예제를 포함하여 질문과 답변을 모두 다루는 게시 가이드가 있습니다.

예: 때때로 누군가가 실제로 실행할 수 있는 작은 예를 제공하는 것이 도움이 됩니다. 예를 들어:

다음과 같은 행렬 x가 있는 경우:

 > 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 >

다음과 같이 차원 이름을 'row' 및 'col' 값으로 갖는 'row', 'col' 및 'value'라는 3개의 열과 8개의 행이 있는 데이터 프레임으로 변환하려면 어떻게 해야 합니까?

 > 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")

)

작은 단어는 특히 중요합니다. 최소한의 재현 가능한 예를 목표로 해야 합니다. 즉, 데이터와 코드는 문제를 설명하기 위해 가능한 한 간단해야 합니다.

편집: 예쁜 코드는 못생긴 코드보다 읽기 쉽습니다. 스타일 가이드를 사용하십시오.


Community Wiki

R.2.14(내 생각에)부터 데이터 텍스트 표현을 read.table .

 df <- read.table(header=TRUE, 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 ")

Community Wiki

때때로 문제는 아무리 노력해도 더 작은 데이터 조각으로는 재현할 수 없으며 합성 데이터에서는 발생하지 않습니다(비록 문제를 재현 하지 않은 합성 데이터 세트를 생성한 방법을 보여주는 것이 유용하지만, 그것은 일부 가설을 배제합니다).

  • 데이터를 웹 어딘가에 게시하고 URL을 제공해야 할 수도 있습니다.
  • 데이터를 일반 대중에게 공개할 수 없지만 전혀 공유할 수 있는 경우 이해 관계자에게 전자 메일을 보내겠다고 제안할 수 있습니다. 그 위에).
  • 데이터를 공개할 수 없는 사람들은 어떤 형태로든 공개하는 것에 민감하기 때문에 실제로 이 작업이 수행되는 것을 보지 못했습니다. 어떤 면에서.

둘 중 하나를 수행할 수 없다면 문제를 해결하기 위해 컨설턴트를 고용해야 할 수도 있습니다.

편집 : 익명화/스크램블링에 대한 두 가지 유용한 SO 질문:


Community Wiki

지금까지의 답변은 재현성 부분에서 분명히 훌륭합니다. 이것은 단지 재현 가능한 예가 질문의 유일한 구성 요소가 될 수 없으며 그렇게 되어서도 안 된다는 것을 명확히 하기 위한 것입니다. 당신이 지금까지 어떻게 거기에 도달하려고 시도했는지뿐만 아니라 당신이 원하는 모습과 문제의 윤곽을 설명하는 것을 잊지 마십시오. 코드가 충분하지 않습니다. 단어도 필요합니다.

다음은 피해야 할 일의 재현 가능한 예입니다(실제 예에서 가져옴, 이름은 무고한 사람을 보호하기 위해 변경됨).


다음은 샘플 데이터와 내가 문제가 있는 기능의 일부입니다.

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

어떻게 하면 달성할 수 있습니까?



Community Wiki

위에서 언급하지 않은 R 예제를 만드는 매우 쉽고 효율적인 방법이 있습니다. 먼저 구조를 정의할 수 있습니다. 예를 들어,

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

'fix' 명령을 실행하면 이 팝업 상자가 나타납니다.

그런 다음 데이터를 수동으로 입력할 수 있습니다. 이것은 큰 것보다 작은 예제에 효율적입니다.


Community Wiki

지침:


질문을 작성하는 주요 목표는 독자가 가능한 한 쉽게 문제를 이해하고 시스템에서 문제를 재현할 수 있도록 하는 것입니다. 이렇게 하려면:

  1. 입력 데이터 제공
  2. 예상 출력 제공
  3. 문제를 간결하게 설명
    • 20줄 이상의 텍스트 + 코드가 있는 경우 뒤로 돌아가서 단순화할 수 있습니다.
    • 문제/오류를 유지하면서 최대한 코드를 단순화하십시오.

이것은 약간의 작업이 필요하지만 다른 사람에게 작업을 요청하기 때문에 공정한 절충안처럼 보입니다.

데이터 제공:


내장 데이터 세트

지금까지 가장 좋은 방법은 기본 제공 데이터 세트에 의존하는 것입니다. 이렇게 하면 다른 사람들이 문제를 해결하기가 매우 쉽습니다. data() 를 입력하여 사용할 수 있는 데이터를 확인합니다. 몇 가지 고전적인 예:

  • iris
  • mtcars
  • ggplot2::diamonds (외부 패키지이지만 거의 모든 사람이 가지고 있음)

내장 데이터 세트를 검사하여 문제에 적합한 데이터 세트를 찾으십시오.

기본 제공 데이터 세트를 사용하도록 문제를 다시 설명할 수 있다면 좋은 답변(및 찬성)을 얻을 가능성이 훨씬 높아집니다.

자체 생성 데이터

문제가 기존 데이터 세트에 표시되지 않는 데이터 유형과 관련된 경우 문제가 나타나는 가능한 가장 작은 데이터 세트를 생성하는 R 코드를 제공하십시오. 예를 들어

 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

당신의 질문에 사람들은 당신이 빨리 하려고 하는 것을 훨씬 더 잘 이해할 것입니다. 예상 결과가 크고 다루기 힘들다면 문제를 단순화하는 방법에 대해 충분히 생각하지 않았을 것입니다(다음 참조).

문제를 간결하게 설명


가장 중요한 것은 질문을 하기 전에 가능한 한 문제를 단순화하는 것입니다. 내장 데이터 세트로 작업하도록 문제를 재구성하면 이와 관련하여 많은 도움이 될 것입니다. 또한 단순화 과정을 거치는 것만으로도 자신의 문제에 대한 답을 얻을 수 있다는 사실을 종종 알게 될 것입니다.

다음은 좋은 질문의 몇 가지 예입니다.

두 경우 모두 사용자의 문제는 사용자가 제공하는 간단한 예제가 아닌 것이 거의 확실합니다. 오히려 그들은 문제의 본질을 추상화하고 간단한 데이터 세트에 적용하여 질문을 던졌습니다.

왜 이 질문에 대한 또 다른 대답인가?


이 답변은 내가 생각하는 모범 사례에 중점을 둡니다. 기본 제공 데이터 세트를 사용하고 결과적으로 기대하는 것을 최소한의 형식으로 제공합니다. 가장 눈에 띄는 답변은 다른 측면에 중점을 둡니다. 나는 이 대답이 어느 정도 눈에 띄게 될 것이라고 기대하지 않습니다. 이것은 초보자 질문에 대한 의견에 링크할 수 있도록 여기에 있습니다.


Community Wiki

dput 을 빠르게 생성하려면 데이터를 클립보드에 복사(일부)하고 R에서 다음을 실행하면 됩니다.

Excel 데이터의 경우:

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

.txt 파일의 데이터:

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

필요한 경우 후자 sep 를 변경할 수 있습니다. 물론 데이터가 클립보드에 있는 경우에만 작동합니다.


Community Wiki

재현 가능한 코드는 도움을 받는 열쇠입니다. 그러나 데이터 덩어리조차 붙여넣는 데 회의적인 사용자가 많이 있습니다. 예를 들어, 민감한 데이터 또는 연구 논문에 사용하기 위해 수집된 원본 데이터로 작업할 수 있습니다.

어떤 이유로 공개적으로 붙여넣기 전에 데이터를 "변형"하는 편리한 기능이 있으면 좋겠다고 생각했습니다. SciencesPo 패키지의 anonymize 기능은 매우 어리석은 일이지만 나에게는 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

익명화 및 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

Community Wiki

예를 들어 데이터가 필요한 경우가 많지만 정확한 데이터를 게시하고 싶지는 않습니다. 기존 라이브러리의 일부 data.frame을 사용하려면 data 명령을 사용하여 가져옵니다.

예,

 data(mtcars)

그런 다음 문제를 해결

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

Community Wiki

dput() 사용하여 스크립트에 쉽게 넣을 수 없는 큰 데이터 세트가 있는 경우 데이터를 pastebin 에 read.table 사용하여 로드하십시오.

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

Henrik에서 영감을 얻었습니다.


Community Wiki

나는 재현 가능한 데이터를 빠르게 공유해야 하는 이 필요성을 해결 하기 위해 웨이크필드 패키지 를 개발 중입니다 dput 이 더 작은 데이터 세트에 대해 잘 작동하지만 우리가 처리하는 많은 문제는 훨씬 더 크기 dput 통해 이러한 큰 데이터 세트를 공유하는 것은 비실용적입니다.

에 대한:

wakefield를 사용하면 사용자가 데이터를 재생산하기 위해 최소한의 코드를 공유할 수 있습니다. 사용자는 n (행 수)을 설정하고 실제 if 데이터(성별, 나이, 소득 등)를 모방하는 사전 설정된 변수 함수(현재 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 .. ... ... ... ... ... ... ... ...

Community Wiki

dput(head(mydata)) 를 사용하여 재현할 수 있도록 데이터에 factor 변수가 있는 경우 여기에 droplevels 를 추가하여 최소화된 데이터 세트에 없는 요인의 수준이 다음과 같이 되도록 하십시오. 예를 최소화 dput 출력에 포함되지 않습니다.

 dput(droplevels(head(mydata)))

Community Wiki

http://old.r-fiddle.org/ 링크가 문제를 공유하는 매우 깔끔한 방법이 될 수 있는지 궁금합니다. 그것은 고유한 ID를 수신하며 SO에 포함하는 것에 대해 생각할 수도 있습니다.


Community Wiki

다음과 같이 콘솔 출력을 붙여넣지 마십시오.

 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") )

우리는 그것을 직접 복사하여 붙여 넣을 수 없습니다.

질문과 답변을 적절하게 재현할 수 있도록 하려면 게시하기 전에 + & > 를 제거하고 다음과 같은 출력 및 주석 #

 #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")

한 가지 더, 특정 패키지의 기능을 사용한 경우 해당 라이브러리를 언급하십시오.


Community Wiki

reprex 를 사용하여 이 작업을 수행할 수 있습니다.

mt1022가 언급했듯이 "... 최소한의 재현 가능한 예제를 생성하기 위한 좋은 패키지는 Tidyverse의 " reprex "입니다.

Tidyverse 에 따르면:

"reprex"의 목표는 문제가 있는 코드를 다른 사람들이 실행하고 고통을 느낄 수 있도록 패키지하는 것입니다.

Tidyverse 웹 사이트에 예가 나와 있습니다.

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

이것이 재현 가능한 예제를 만드는 가장 간단한 방법 이라고 생각합니다.


Community Wiki

내가 매우 흥미롭게 찾은 위의 모든 답변 외에도 여기에서 논의한 것처럼 때때로 매우 쉬울 수 있습니다. R에 대한 도움을 얻기 위해 재현 가능한 최소 예제를 만드는 방법

임의의 벡터를 만들 수있는 많은 방법이있다 R의 임의의 값이 소수점 반올림과 100 번호 벡터 생성 또는 R의 임의의 행렬은 :

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

차원 등의 여러 가지 이유로 주어진 데이터를 공유하는 것이 매우 어려운 경우가 있음을 유의하십시오. 그러나 위의 모든 답변은 훌륭하고 재현 가능한 데이터 예제를 만들고 싶을 때 생각하고 사용하는 것이 매우 중요합니다. . 그러나 데이터를 원본처럼 대표하도록 하려면(OP가 원본 데이터를 공유할 수 없는 경우) 데이터 예제와 함께 일부 정보를 추가하는 것이 좋습니다(데이터를 mydf1이라고 하는 경우).

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

또한 데이터 구조 가 될 수 있는 데이터의 유형, 길이 및 속성을 알아야 합니다.

 #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))

Community Wiki

다음은 몇 가지 제안 사항입니다.

  • 기본 R 데이터 세트를 사용해보십시오.
  • 자신의 데이터 세트가 있는 경우 dput 포함하여 다른 사람들이 더 쉽게 도울 수 있도록 합니다.
  • install.package() 사용하지 마십시오. require 또는 library 만 사용하면 사람들이 이해할 것입니다.
  • 간결하게 시도하고,

    • 일부 데이터 세트가 있습니다.
    • 가능한 한 간단하게 필요한 출력을 설명하십시오.
    • 질문하기 전에 스스로 하라
  • 이미지를 업로드하기 쉽기 때문에 플롯이 있으면 업로드하십시오.
  • 있을 수 있는 오류도 포함하십시오.

이 모든 것은 재현 가능한 예의 일부입니다.


Community Wiki

예상되는 결과를 보여주기 testthat 패키지의 기능을 사용하는 것이 좋습니다. 따라서 오류 없이 실행될 때까지 다른 사람들이 코드를 변경할 수 있습니다. 이것은 그들이 당신의 텍스트 설명을 해독할 필요가 없다는 것을 의미하기 때문에 당신을 돕고자 하는 사람들의 부담을 덜어줍니다. 예를 들어

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

"나는 x가 10과 같거나 초과하는 y에 대해 1.23이 될 것이라고 생각하고 그렇지 않으면 3.21이 될 것이라고 생각하지만 결과를 얻지 못했습니다"보다 명확합니다. 이 어리석은 예에서도 코드가 단어보다 더 명확하다고 생각합니다. testthat 사용하면 도우미가 코드에 집중할 수 있으므로 시간이 절약되고 게시하기 전에 문제를 해결했는지 알 수 있습니다.


Community Wiki

출처 : http:www.stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example

반응형