Dlaczego ` ["jest lepsze niż "podzbiór"?
Kiedy muszę filtrować dane.frame, czyli wyodrębnianie wierszy spełniających określone warunki, wolę użyć funkcji subset
:
subset(airquality, Month == 8 & Temp > 90)
Zamiast funkcji [
:
airquality[airquality$Month == 8 & airquality$Temp > 90, ]
Są dwa główne powody, dla których preferuję:
Uważam, że kod czyta się lepiej, od lewej do prawej. Nawet ludzie, którzy nic nie wiedzą o R, mogą powiedzieć, co robi powyższe stwierdzenie
subset
.Ponieważ kolumny mogą być określane jako zmienne w
select
ekspresja, mogę zapisać kilka naciśnięć klawiszy. W powyższym przykładzie musiałem tylko raz wpisaćairquality
zsubset
, ale trzy razy z[
.
Więc żyłem szczęśliwie, używałem subset
wszędzie, ponieważ jest krótszy i czyta się lepiej, nawet opowiadając się za jego pięknem moim koleżankom. Ale wczoraj mój świat się rozpadł. Podczas czytania dokumentacji subset
zauważam ten dział:
Ostrzeżenie
Jest to Funkcja wygodna przeznaczona do użytku interaktywnie. Do programowania lepiej jest używać standardowych funkcji podzbiorów, takich jak [, a w szczególności niestandardowa ocena podzbioru argumentów może mieć nieprzewidziane konsekwencje.
Mógłby ktoś pomóc wyjaśnić, co autorzy mają na myśli?
Po Pierwsze, co mają na myśli przez " do interaktywnego użytku "? Wiem, co to jest sesja interaktywna, w przeciwieństwie do skryptu uruchamianego w trybie wsadowym, ale nie widzę, jaką różnicę powinno to zrobić.
Wtedy, może Proszę wyjaśnić "niestandardową ocenę podzbioru argumentów " i dlaczego jest to niebezpieczne, może podać przykład?
2 answers
Na to pytanie odpowiedziała dobrze w komentarzach @ James, wskazując na doskonałe wyjaśnienie przez Hadley Wickham niebezpieczeństw subset
(i podobnych funkcji) [tutaj] . Przeczytaj to!
Jest to dość długa lektura, więc pomocne może być zapisanie tutaj przykładu, którego używa Hadley, który najbardziej bezpośrednio odnosi się do pytania " co może pójść nie tak?":
Hadley sugeruje następujący przykład: załóżmy, że chcemy podzestawić, a następnie zmienić kolejność ramki danych, używając następującego funkcje:
scramble <- function(x) x[sample(nrow(x)), ]
subscramble <- function(x, condition) {
scramble(subset(x, condition))
}
subscramble(mtcars, cyl == 4)
Zwraca błąd:
W tym celu prosimy o zapoznanie się z naszą polityką prywatności.]}
Ponieważ R nie wie już gdzie znaleźć obiekt o nazwie 'cyl'. Zwraca również uwagę na naprawdę dziwaczne rzeczy, które mogą się zdarzyć, jeśli przez przypadek istnieje obiekt o nazwie " cyl " w globalnym środowisku: {]}
cyl <- 4
subscramble(mtcars, cyl == 4)
cyl <- sample(10, 100, rep = T)
subscramble(mtcars, cyl == 4)
(Uruchom je i przekonaj się sam, to dość szalone.)Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-06 02:46:49
Również [
jest szybsze:
require(microbenchmark)
microbenchmark(subset(airquality, Month == 8 & Temp > 90),airquality[airquality$Month == 8 & airquality$Temp > 90,])
Unit: microseconds
expr min lq median uq max neval
subset(airquality, Month == 8 & Temp > 90) 301.994 312.1565 317.3600 349.4170 500.903 100
airquality[airquality$Month == 8 & airquality$Temp > 90, ] 234.807 239.3125 244.2715 271.7885 340.058 100
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-05 15:48:23