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

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

  2. 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 z subset, 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?

Author: Bhargav Rao, 2012-03-25

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.)
 215
Author: joran,
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
 23
Author: bartektartanus,
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