주어진 데이터 세트에서 실행할 수 있는 오류를 재현하는 데 필요한 최소한의 실행 가능한 코드
사용된 패키지, 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
참고: 널리 사용되지만 데이터 프레임의 이름을 dfdf() 는 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
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() 및 기타 많은 함수와 같은 임의의 함수가 항상 동일한 결과를 반환할 수 있습니다. 예:
1참고:set.seed() 의 출력은 R >3.6.0과 이전 버전 간에 다릅니다. 임의 프로세스에 사용한 R 버전을 지정하고 오래된 질문을 따를 때 약간 다른 결과가 나온다고 놀라지 마십시오. 이러한 경우에 동일한 결과를 얻으려면 RNGversion() 전에 set.seed() 사용할 수 있습니다(예: RNGversion("3.5.2") ).
가장 중요한 점은 다음과 같습니다. 문제가 무엇인지 보기 위해 실행할 수 있는 작은 코드 조각을 만드십시오. 이에 유용한 함수는 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개의 행이 있는 데이터 프레임으로 변환하려면 어떻게 해야 합니까?
지금까지의 답변은 재현성 부분에서 분명히 훌륭합니다. 이것은 단지 재현 가능한 예가 질문의 유일한 구성 요소가 될 수 없으며 그렇게 되어서도 안 된다는 것을 명확히 하기 위한 것입니다. 당신이 지금까지 어떻게 거기에 도달하려고 시도했는지뿐만 아니라 당신이 원하는 모습과 문제의 윤곽을 설명하는 것을 잊지 마십시오. 코드가 충분하지 않습니다. 단어도 필요합니다.
다음은 피해야 할 일의 재현 가능한 예입니다(실제 예에서 가져옴, 이름은 무고한 사람을 보호하기 위해 변경됨).
다음은 샘플 데이터와 내가 문제가 있는 기능의 일부입니다.
code code code code code (40 or so lines of it)
어떻게 하면 달성할 수 있습니까?
Community Wiki
위에서 언급하지 않은 R 예제를 만드는 매우 쉽고 효율적인 방법이 있습니다. 먼저 구조를 정의할 수 있습니다. 예를 들어,
당신의 질문에 사람들은 당신이 빨리 하려고 하는 것을 훨씬 더 잘 이해할 것입니다. 예상 결과가 크고 다루기 힘들다면 문제를 단순화하는 방법에 대해 충분히 생각하지 않았을 것입니다(다음 참조).
문제를 간결하게 설명
가장 중요한 것은 질문을 하기 전에 가능한 한 문제를 단순화하는 것입니다. 내장 데이터 세트로 작업하도록 문제를 재구성하면 이와 관련하여 많은 도움이 될 것입니다. 또한 단순화 과정을 거치는 것만으로도 자신의 문제에 대한 답을 얻을 수 있다는 사실을 종종 알게 될 것입니다.
두 경우 모두 사용자의 문제는 사용자가 제공하는 간단한 예제가 아닌 것이 거의 확실합니다. 오히려 그들은 문제의 본질을 추상화하고 간단한 데이터 세트에 적용하여 질문을 던졌습니다.
왜 이 질문에 대한 또 다른 대답인가?
이 답변은 내가 생각하는 모범 사례에 중점을 둡니다. 기본 제공 데이터 세트를 사용하고 결과적으로 기대하는 것을 최소한의 형식으로 제공합니다. 가장 눈에 띄는 답변은 다른 측면에 중점을 둡니다. 나는 이 대답이 어느 정도 눈에 띄게 될 것이라고 기대하지 않습니다. 이것은 초보자 질문에 대한 의견에 링크할 수 있도록 여기에 있습니다.
Community Wiki
dput 을 빠르게 생성하려면 데이터를 클립보드에 복사(일부)하고 R에서 다음을 실행하면 됩니다.
나는 재현 가능한 데이터를 빠르게 공유해야 하는 이 필요성을 해결 하기 위해 웨이크필드 패키지 를 개발 중입니다 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")
차원 등의 여러 가지 이유로 주어진 데이터를 공유하는 것이 매우 어려운 경우가 있음을 유의하십시오. 그러나 위의 모든 답변은 훌륭하고 재현 가능한 데이터 예제를 만들고 싶을 때 생각하고 사용하는 것이 매우 중요합니다. . 그러나 데이터를 원본처럼 대표하도록 하려면(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 사용하면 도우미가 코드에 집중할 수 있으므로 시간이 절약되고 게시하기 전에 문제를 해결했는지 알 수 있습니다.