Podczas omawiania wyników ze współpracownikami, nauczania, wysyłania raportu o błędach lub szukania wskazówek na temat list mailingowych i tutaj na temat przepełnienia stosu często powtarzalny przykład jest często zadawany i zawsze pomocny.
Jakie są twoje wskazówki, jak stworzyć doskonały przykład? Jak wklejasz struktury danychrw formacie tekstowym? Jakie inne informacje powinieneś podać?
Czy istnieją inne sztuczki oprócz korzystania dput()
, dump()
albo structure()
? Kiedy należy dołączyć library()
lub require()
oświadczenia? Który zastrzeżone słów należy unikać, w uzupełnieniu do c
, df
, data
, itd.?
Jak można zrobić coś wspaniałego r odtwarzalny przykład?
Odpowiedzi:
Minimalny powtarzalne przykład składa się z następujących elementów:
set.seed()
) dla odtwarzalności 1Przykłady dobrych minimalnych odtwarzalnych przykładów można znaleźć w plikach pomocy używanej funkcji. Zasadniczo cały podany tam kod spełnia wymagania minimalnego odtwarzalnego przykładu: dostarczane są dane, zapewniony jest minimalny kod i wszystko jest możliwe do uruchomienia. Zobacz także pytania dotyczące przepełnienia stosu z dużą ilością pozytywnych opinii.
Tworzenie minimalnego zestawu danych
W większości przypadków można to łatwo zrobić, po prostu zapewniając ramkę wektor / dane z pewnymi wartościami. Lub możesz użyć jednego z wbudowanych zestawów danych, które są dostarczane z większością pakietów.
Można zobaczyć pełną listę wbudowanych zestawów danych
library(help = "datasets")
. Każdy zestaw danych zawiera krótki opis i można uzyskać więcej informacji, na przykład o tym,?mtcars
gdzie „mtcars” jest jednym z zestawów danych na liście. Inne pakiety mogą zawierać dodatkowe zestawy danych.Wykonanie wektora jest łatwe. Czasami konieczne jest dodanie do niej losowości i jest do tego cała liczba funkcji.
sample()
może randomizować wektor lub dać losowy wektor z kilkoma wartościami.letters
to użyteczny wektor zawierający alfabet. Można to wykorzystać do tworzenia czynników.Kilka przykładów:
x <- rnorm(10)
dla rozkładu normalnego,x <- runif(10)
dla rozkładu równomiernego, ...x <- sample(1:10)
dla wektora 1:10 w losowej kolejności.x <- sample(letters[1:4], 20, replace = TRUE)
W przypadku matryc można użyć
matrix()
np .:Tworzenie ramek danych można wykonać za pomocą
data.frame()
. Należy zwrócić uwagę na nazwy wpisów w ramce danych i nie komplikować ich zbytnio.Przykład :
W przypadku niektórych pytań mogą być potrzebne określone formaty. Dla nich, można użyć dowolnego z określonych
as.someType
funkcji:as.factor
,as.Date
,as.xts
, ... To w połączeniu z wektorem i / lub ramka danych sztuczek.Skopiuj swoje dane
Jeśli masz jakieś dane, które byłyby zbyt trudne do skonstruowania za pomocą tych wskazówek, to zawsze można zrobić podzbiór oryginalnego danych, używając
head()
,subset()
lub indeksy. Następnie użyj,dput()
aby dać nam coś, co można natychmiast umieścić w R:Jeśli ramka danych ma czynnik z wieloma poziomami, dane
dput
wyjściowe mogą być nieporęczne, ponieważ nadal będzie zawierać listę wszystkich możliwych poziomów czynników, nawet jeśli nie są one obecne w podzbiorze danych. Aby rozwiązać ten problem, możesz użyćdroplevels()
funkcji. Zauważ, że gatunek jest czynnikiem z tylko jednym poziomem:Podczas korzystania
dput
możesz także chcieć uwzględnić tylko odpowiednie kolumny:Innym zastrzeżeniem
dput
jest to, że nie będzie działać dladata.table
obiektów z kluczami lub dla gruptbl_df
(klasgrouped_df
) zdplyr
. W takich przypadkach można przekształcić z powrotem do regularnego ramki danych przed udostępnianiedput(as.data.frame(my_data))
.W najgorszym przypadku można podać reprezentację tekstową, którą można odczytać za pomocą
text
parametruread.table
:Produkcja minimalnego kodu
To powinna być łatwa część, ale często nie jest. Czego nie powinieneś robić, to:
Co powinieneś zrobić, to:
library()
)unlink()
)op <- par(mfrow=c(1,2)) ...some code... par(op)
)Podaj dodatkowe informacje
W większości przypadków wystarczy wersja R i system operacyjny. Kiedy pojawiają się konflikty z pakietami, podanie wyniku
sessionInfo()
może naprawdę pomóc. Mówiąc o połączeniach z innymi aplikacjami (czy to przez ODBC, czy cokolwiek innego), należy również podać numery wersji tych aplikacji, a jeśli to możliwe, także niezbędne informacje na temat konfiguracji.Jeśli używasz R w R Studio przy użyciu
rstudioapi::versionInfo()
mogą być pomocne zgłosić swoją wersję RStudio.Jeśli masz problem z konkretnym pakietem, możesz podać jego wersję, podając wynik działania
packageVersion("name of the package")
.1 Uwaga: Wydajność
set.seed()
różni się między R> 3.6.0 i poprzednimi wersjami. Podaj, której wersji R użyłeś do losowego procesu i nie zdziw się, jeśli uzyskasz nieco inne wyniki podczas odpowiedzi na stare pytania. Aby uzyskać taki sam wynik w takich przypadkach, możesz wcześniej użyć funkcjiRNGversion()
-fset.seed()
(npRNGversion("3.5.2")
. :) .źródło
dput
jeśli ramka danych jest bardzo duża, a problem generowany jest przez środek ramki danych? Czy istnieje sposób nadput
odtworzenie środkowej części danych, powiedzmy wiersze od 60 do 70?tmp <- mydf[50:70,]
po której następujedput(mydf)
. Jeśli ramka danych jest naprawdę duża, spróbuj wyizolować problem i po prostu prześlij kilka wierszy, które powodują problem.head
lubdput
ograniczyć dane do poziomu N rekurencyjnie? Próbuję wymyślić powtarzalny przykład, a moje dane to lista ramek danych.dput(head(myDataObj))
Wydaje się więc nie wystarczać, ponieważ generuje plik wyjściowy o rozmiarze 14 MB.(Oto moja rada z Jak napisać powtarzalny przykład . Starałem się streścić, ale słodko)
Jak napisać powtarzalny przykład.
Najprawdopodobniej uzyskasz dobrą pomoc z problemem R, jeśli podasz powtarzalny przykład. Powtarzalny przykład pozwala komuś innemu odtworzyć twój problem, po prostu kopiując i wklejając kod R.
Są cztery rzeczy, które musisz uwzględnić, aby Twój przykład był odtwarzalny: wymagane pakiety, dane, kod i opis środowiska R.
Pakiety powinny być ładowane u góry skryptu, aby łatwo było zobaczyć, które z nich są potrzebne w przykładzie.
Najłatwiejszym sposobem na włączenie danych do wiadomości e-mail lub pytania o przepełnienie stosu jest
dput()
wygenerowanie kodu R w celu jego odtworzenia. Na przykład, aby odtworzyćmtcars
zestaw danych w R, wykonaj następujące czynności:dput(mtcars)
w R.mtcars <-
a następnie wklej.Poświęć trochę czasu na upewnienie się, że Twój kod jest łatwy do odczytania dla innych:
upewnij się, że użyłeś spacji, a nazwy zmiennych są zwięzłe, ale mają charakter informacyjny
użyj komentarzy, aby wskazać, gdzie leży twój problem
postaraj się usunąć wszystko, co nie jest związane z problemem.
Im krótszy jest Twój kod, tym łatwiej go zrozumieć.
Uwzględnij wynik
sessionInfo()
w komentarzu w kodzie. To podsumowuje twoje środowisko R i ułatwia sprawdzenie, czy używasz nieaktualnego pakietu.Możesz sprawdzić, czy rzeczywiście stworzyłeś powtarzalny przykład, rozpoczynając nową sesję R i wklejając skrypt.
Przed umieszczeniem całego kodu w wiadomości e-mail, rozważ umieszczenie go w Gist github . Dzięki temu twój kod będzie ładnie podświetlany pod względem składni i nie musisz się martwić o to, że system poczty e-mail zakłóci wszystko.
źródło
reprex
intidyverse
jest dobrym pakietem do tworzenia minimalnego, powtarzalnego przykładu: github.com/tidyverse/reprexOsobiście wolę wkładki „one”. Coś wzdłuż linii:
Struktura danych powinna naśladować ideę problemu pisarza, a nie dokładną strukturę dosłowną. Naprawdę to doceniam, gdy zmienne nie nadpisują moich własnych zmiennych lub nie daj Boże, funkcje (jak
df
).Alternatywnie można wyciąć kilka rogów i wskazać na wcześniej istniejący zestaw danych, na przykład:
Nie zapomnij wspomnieć o specjalnych pakietach, których możesz używać.
Jeśli próbujesz pokazać coś na większych obiektach, możesz spróbować
Jeśli pracujesz z danymi przestrzennymi za pośrednictwem
raster
pakietu, możesz wygenerować losowe dane. Wiele przykładów można znaleźć w winiecie opakowania, ale oto mały samorodek.Jeśli potrzebujesz jakiegoś obiektu przestrzennego w postaci zaimplementowanej w
sp
, możesz pobrać niektóre zestawy danych za pomocą plików zewnętrznych (takich jak plik kształtu ESRI) w pakietach „przestrzennych” (zobacz Widok przestrzenny w widokach zadań).źródło
sample
lubrunif
jest to rozsądneset.seed
. Przynajmniej taką sugestię otrzymałem przy tworzeniu przykładów dotyczących próbkowania lub generowania liczb losowych.runif
lubsample
nie są zdezorientowani że nie mogą uzyskać tych samych danych.Zainspirowany tym postem, używam teraz przydatnej funkcji,
reproduce(<mydata>)
gdy muszę wysłać wiadomość do StackOverflow.SZYBKIE INSTRUKCJE
Jeśli
myData
jest to nazwa obiektu do odtworzenia, uruchom następujące polecenie w języku R:Detale:
Ta funkcja jest inteligentnym opakowaniem
dput
i wykonuje następujące czynności:dput
wynikobjName <- ...
aby można go było łatwo skopiować i wkleić, ale ...Źródło jest dostępne tutaj:
Przykład:
DF wynosi około 100 x 102. Chcę spróbować 10 wierszy i kilku konkretnych kolumn
Daje następujące dane wyjściowe:
Zauważ też, że całość danych wyjściowych jest w ładnym pojedynczym, długim wierszu, a nie wysokim akapicie pociętych linii. Ułatwia to czytanie postów na pytania SO, a także łatwiejsze kopiowanie i wklejanie.
Aktualizacja października 2013:
Możesz teraz określić, ile linii tekstu wyjściowego zajmie (tj. Co wkleisz do StackOverflow). Użyj
lines.out=n
do tego argumentu. Przykład:reproduce(DF, cols=c(1:3, 17, 23), lines.out=7)
daje:źródło
Oto dobry przewodnik .
Najważniejsze jest to: Upewnij się, że wykonałeś mały fragment kodu, który możemy uruchomić, aby zobaczyć, na czym polega problem . Przydatną funkcją do tego jest
dput()
, ale jeśli masz bardzo duże dane, możesz utworzyć niewielki przykładowy zestaw danych lub użyć tylko pierwszych 10 wierszy.EDYTOWAĆ:
Upewnij się także, że sam zidentyfikowałeś problem. Przykładem nie powinien być cały skrypt R z komunikatem „W wierszu 200 wystąpił błąd”. Jeśli używasz narzędzi do debugowania w R (uwielbiam
browser()
) i Google, powinieneś być w stanie naprawdę określić, gdzie jest problem i odtworzyć trywialny przykład, w którym to samo nie działa.źródło
Lista mailingowa R-help zawiera przewodnik, który obejmuje zarówno zadawanie pytań, jak i udzielanie odpowiedzi, w tym przykład generowania danych:
Słowo „ małe” jest szczególnie ważne. Powinieneś dążyć do minimalnego odtwarzalnego przykładu, co oznacza, że dane i kod powinny być tak proste, jak to możliwe, aby wyjaśnić problem.
EDYCJA: Ładny kod jest łatwiejszy do odczytania niż brzydki kod. Skorzystaj z przewodnika po stylu .
źródło
Od R.2.14 (tak myślę) możesz przesyłać swoją reprezentację tekstu danych bezpośrednio do
read.table
:źródło
Czasami problem tak naprawdę nie daje się odtworzyć przy mniejszym kawałku danych, bez względu na to, jak bardzo się starasz, i nie występuje w przypadku danych syntetycznych (chociaż przydatne jest pokazanie, w jaki sposób utworzono zestawy danych syntetycznych, które nie odtworzyły problemu, ponieważ wyklucza to pewne hipotezy).
Jeśli nie możesz tego zrobić, prawdopodobnie musisz zatrudnić konsultanta, aby rozwiązać problem ...
edycja : Dwa przydatne pytania SO do anonimizacji / mieszania:
źródło
fitdistr
ifitdistrplus
.Dotychczasowe odpowiedzi są oczywiście świetne dla części odtwarzalności. Ma to jedynie na celu wyjaśnienie, że odtwarzalny przykład nie może i nie powinien być jedynym elementem pytania. Nie zapomnij wyjaśnić, jak ma on wyglądać i konturów problemu, a nie tylko tego, jak próbowałeś się tam dostać. Kod to za mało; potrzebujesz także słów.
Oto powtarzalny przykład tego, czego należy unikać (zaczerpnięty z prawdziwego przykładu, nazwy zmieniono, aby chronić niewinnych):
Oto przykładowe dane i część funkcji, z którą mam problem.
Jak mogę to osiągnąć?
źródło
Mam bardzo łatwy i skuteczny sposób na stworzenie przykładu R, który nie został wspomniany powyżej. Możesz najpierw zdefiniować swoją strukturę. Na przykład,
Następnie możesz wprowadzić swoje dane ręcznie. Jest to skuteczne w przypadku mniejszych przykładów niż dużych.
źródło
dput(mydata)
for (d in data) {...}
.Aby szybko utworzyć
dput
ze swoich danych, możesz po prostu skopiować (część) danych do schowka i uruchomić w R:dla danych w Excelu:
dla danych w pliku txt:
W
sep
razie potrzeby możesz zmienić te ostatnie. Działa to tylko wtedy, gdy twoje dane są oczywiście w schowku.źródło
Wytyczne:
Twoim głównym celem przy tworzeniu pytań powinno być ułatwienie czytelnikom zrozumienia i odtworzenia Twojego problemu w ich systemach. Aby to zrobić:
To wymaga trochę pracy, ale wydaje się, że jest to sprawiedliwy kompromis, ponieważ prosisz innych o wykonanie pracy za Ciebie.
Podanie danych:
Wbudowane zestawy danych
Najlepszym rozwiązaniem zdecydowanie ma polegać na wbudowanej zbiorów danych. Ułatwia to innym pracę nad twoim problemem. Wpisz
data()
w wierszu R, aby zobaczyć, jakie dane są dostępne. Niektóre klasyczne przykłady:iris
mtcars
ggplot2::diamonds
(pakiet zewnętrzny, ale prawie wszyscy go mają)Zobacz ten SO QA, aby znaleźć zestawy danych odpowiednie dla Twojego problemu.
Jeśli jesteś w stanie przeformułować swój problem, aby użyć wbudowanych zestawów danych, znacznie bardziej prawdopodobne jest uzyskanie dobrych odpowiedzi (i pozytywnych opinii).
Dane wygenerowane samodzielnie
Jeśli twój problem jest bardzo specyficzny dla typu danych, który nie jest reprezentowany w istniejących zestawach danych, podaj kod R, który generuje najmniejszy możliwy zestaw danych, na którym pojawia się twój problem. Na przykład
Teraz ktoś, kto próbuje odpowiedzieć na moje pytanie, może skopiować / wkleić te dwa wiersze i natychmiast rozpocząć pracę nad problemem.
dput
W ostateczności można użyć
dput
do przekształcenia obiektu danych w kod R (npdput(myData)
.). Mówię jako „ostatnią deską ratunku”, ponieważ wynikidput
często są dość nieporęczne, irytujące w kopiowaniu-wklejaniu i przesłaniają resztę pytania.Zapewnij oczekiwany wynik:
Ktoś kiedyś powiedział:
Jeśli możesz dodać coś w stylu „Spodziewałem się tego wyniku”:
na twoje pytanie, ludzie znacznie częściej rozumieją, co próbujesz zrobić. Jeśli oczekiwany wynik jest duży i nieporęczny, prawdopodobnie nie zastanawiałeś się wystarczająco, jak uprościć swój problem (patrz dalej).
Wyjaśnij zwięźle swój problem
Najważniejsze jest, aby maksymalnie uprościć swój problem, zanim zadasz pytanie. Przeformułowanie problemu do pracy z wbudowanymi zestawami danych bardzo pomoże w tym względzie. Często też przekonasz się, że po prostu przez uproszczenie rozwiążesz swój problem.
Oto kilka przykładów dobrych pytań:
W obu przypadkach problemy użytkownika prawie na pewno nie wynikają z prostych przykładów, które podają. Zamiast tego wyodrębnili naturę swojego problemu i zastosowali go do prostego zestawu danych, aby zadać pytanie.
Dlaczego jeszcze jedna odpowiedź na to pytanie?
Ta odpowiedź koncentruje się na tym, co uważam za najlepszą praktykę: używaj wbudowanych zestawów danych i zapewniaj to, czego oczekujesz w wyniku w minimalnej formie. Najważniejsze odpowiedzi koncentrują się na innych aspektach. Nie oczekuję, że ta odpowiedź zyska na znaczeniu; jest to tutaj wyłącznie po to, bym mógł link do niego w komentarzach do pytań dla początkujących.
źródło
Powtarzalny kod jest kluczem do uzyskania pomocy. Jednak wielu użytkowników może sceptycznie wkleić nawet część swoich danych. Mogą na przykład pracować z danymi wrażliwymi lub nad danymi oryginalnymi zebranymi do wykorzystania w pracy badawczej. Z jakiegokolwiek powodu pomyślałem, że byłoby miło mieć przydatną funkcję do „deformowania” moich danych przed wklejeniem ich publicznie.
anonymize
Funkcji z pakietuSciencesPo
jest bardzo głupie, ale dla mnie to działa ładnie zdput
funkcji.Następnie anonimizuję to:
Można również spróbować pobrać kilka zmiennych zamiast całych danych przed zastosowaniem polecenia anonimizacji i polecenia dput.
źródło
Często potrzebujesz pewnych danych, ale nie chcesz publikować dokładnych danych. Aby użyć istniejącej biblioteki data.frame w ustalonej bibliotece, użyj polecenia data, aby ją zaimportować.
na przykład,
a następnie zrób problem
źródło
mtcars
iiris
zestawy danych) tak naprawdę nie wymaga użyciadata
wywołania.Jeśli masz duży zestaw danych, którego nie można łatwo umieścić w skrypcie
dput()
, opublikuj swoje dane w pastebin i załaduj je za pomocąread.table
:Inspirowany @Henrik .
źródło
Zajmuję się Wakefield pakiet do tego wymogu, aby szybko udostępniać dane powtarzalne, czasami
dput
działa prawidłowo dla mniejszych zbiorów danych, ale wiele problemów mamy do czynienia są znacznie większe, dzieląc tak dużego zestawu danych poprzezdput
to niepraktyczne.O:
wakefield pozwala użytkownikowi współdzielić minimalny kod do reprodukcji danych. Użytkownik ustawia
n
(liczbę wierszy) i określa dowolną liczbę predefiniowanych funkcji zmiennych (obecnie jest ich 70), które naśladują rzeczywiste dane (np. Płeć, wiek, dochód itp.)Instalacja:
Obecnie (2015-06-11) wakefield jest pakietem GitHub, ale w końcu przejdzie do CRAN po napisaniu testów jednostkowych. Aby szybko zainstalować, użyj:
Przykład:
Oto przykład:
Daje to:
źródło
Jeśli masz w danych jedną lub więcej
factor
zmiennych, które chcesz odtworzyćdput(head(mydata))
, rozważ dodaniedroplevels
tej wartości, aby poziomy czynników nieobecnych w zminimalizowanym zbiorze danych nie zostały uwzględnione w danychdput
wyjściowych, aby zminimalizuj przykład :źródło
Zastanawiam się, czy link http://old.r-fiddle.org/ mógłby być bardzo dobrym sposobem na udostępnienie problemu. Otrzymuje unikalny identyfikator, a nawet można by pomyśleć o osadzeniu go w SO.
źródło
Nie wklejaj danych wyjściowych konsoli w ten sposób:
Nie możemy skopiować i wkleić go bezpośrednio.
Aby pytania i odpowiedzi były poprawnie odtwarzalne, spróbuj je usunąć
+
i>
opublikować, a następnie wstaw#
wyniki i komentarze w następujący sposób:Jeszcze jedna rzecz, jeśli użyłeś dowolnej funkcji z określonego pakietu, wspomnij o tej bibliotece.
źródło
>
i dodajesz#
ręcznie, czy jest to automatyczny sposób?>
ręcznie. Ale na dodatek#
używamCtrl+Shift+C
skrótu wRStudio
edytorze.Możesz to zrobić za pomocą przedrostka .
Jak zauważył mt1022 , „... dobrym pakietem do tworzenia minimalnego, powtarzalnego przykładu jest „ reprezentacja ” z tidyverse ”.
Według Tidyverse :
Przykład podano na stronie internetowej Tidyverse .
Myślę, że jest to najprostszy sposób na stworzenie odtwarzalnego przykładu.
źródło
Oprócz wszystkich powyższych odpowiedzi, które uznałem za bardzo interesujące, czasami może być bardzo łatwe, ponieważ zostało to omówione tutaj: - JAK ZROBIĆ MINIMALNY PRZYKŁAD REPRODUKOWALNY, ABY POMÓC Z R
Istnieje wiele sposobów tworzenia losowego wektora Utwórz wektor o liczbie 100 z losowymi wartościami w R zaokrąglonymi do 2 miejsc po przecinku lub losową macierzą w R
Należy pamiętać, że czasami bardzo trudno jest udostępnić dane z różnych powodów, takich jak wymiar itp. Jednak wszystkie powyższe odpowiedzi są świetne i bardzo ważne, aby przemyśleć i wykorzystać je, gdy chcemy stworzyć przykładowy odtwarzalny przykład. Należy jednak pamiętać, że aby dane były tak reprezentatywne jak oryginalne (w przypadku gdy OP nie może udostępnić oryginalnych danych), dobrze jest dodać pewne informacje z przykładem danych jako (jeśli nazywamy dane mydf1)
Ponadto należy znać typ, długość i atrybuty danych, które mogą być strukturami danych
źródło
Oto niektóre z moich sugestii:
dput
, aby inni mogli łatwiej ci pomócinstall.package()
chyba że jest to naprawdę konieczne, ludzie zrozumieją, czy po prostu używaszrequire
lublibrary
Staraj się być zwięzły,
Wszystko to jest częścią odtwarzalnego przykładu.
źródło
dput()
zostało wspomniane wcześniej, a wiele z nich przypomina tylko standardowe wytyczne SO.install.package
funkcją zawartą w przykładzie, która nie jest tak naprawdę konieczna (moim zdaniem). Ponadto użycie domyślnego zestawu danych R ułatwiłoby powtarzalność. Wytyczne SO nie mówiły konkretnie o tych tematach. Co więcej, miało to na celu wyrażenie mojej opinii i są to te, z którymi najczęściej się spotkałem.Dobrym pomysłem jest użycie funkcji z
testthat
pakietu, aby pokazać, czego się spodziewasz. Dlatego inne osoby mogą zmieniać Twój kod, dopóki nie zostanie uruchomiony bez błędów. Zmniejsza to ciężar tych, którzy chcieliby ci pomóc, ponieważ oznacza to, że nie muszą dekodować twojego opisu tekstowego. Na przykładjest jaśniejsze niż „Myślę, że x wyniesie 1,23 dla y równego lub przekraczającego 10, a w przeciwnym razie 3,21, ale nie uzyskałem żadnego wyniku”. Nawet w tym głupim przykładzie kod wydaje się jaśniejszy niż słowa. Użycie
testthat
pozwala pomocnikowi skoncentrować się na kodzie, co pozwala zaoszczędzić czas, i pozwala mu wiedzieć, że rozwiązali problem, zanim go opublikują.źródło