¿Por qué “ `mejor que` subconjunto`?

Cuando necesito filtrar un data.frame, es decir, extraer filas que cumplen ciertas condiciones, prefiero usar la función de subset :

 subset(airquality, Month == 8 & Temp > 90) 

En lugar de la [ función:

 airquality[airquality$Month == 8 & airquality$Temp > 90, ] 

Hay dos razones principales para mi preferencia:

  1. Encuentro que el código se lee mejor, de izquierda a derecha. Incluso las personas que no saben nada sobre R podrían decir lo que está haciendo la statement del subset anterior.

  2. Como las columnas se pueden denominar variables en la expresión de select , puedo guardar algunas pulsaciones de teclas. En mi ejemplo anterior, solo tuve que escribir airquality una vez con subset , pero tres veces con [ .

Así que estaba viviendo feliz, usando subset todas partes porque es más corto y se lee mejor, incluso abogando por su belleza para mis compañeros codificadores R. Pero ayer mi mundo se vino abajo. Mientras leo la documentación del subset , veo esta sección:

Advertencia

Esta es una función de conveniencia diseñada para su uso de manera interactiva. Para la progtwigción, es mejor utilizar las funciones de subconjunto estándar como [, y en particular la evaluación no estándar del subconjunto de argumentos puede tener consecuencias imprevistas.

¿Podría alguien ayudar a aclarar lo que los autores quieren decir?

Primero, ¿qué quieren decir con ” para usar de forma interactiva “? Sé lo que es una sesión interactiva, a diferencia de un script ejecutado en modo BATCH, pero no veo la diferencia que debería hacer.

Entonces, ¿podría explicar ” el subconjunto de evaluación no estándar del argumento ” y por qué es peligroso, quizás brinde un ejemplo?

Esta pregunta fue bien respondida en los comentarios de @James, señalando una excelente explicación de Hadley Wickham sobre los peligros del subset (y funciones similares) [aquí] . Ve a leerlo!

Es una lectura algo larga, por lo que puede ser útil registrar aquí el ejemplo que utiliza Hadley que aborda más directamente la pregunta de “¿qué puede salir mal?”:

Hadley sugiere el siguiente ejemplo: supongamos que queremos subconjunto y luego reordenar un dataframe usando las siguientes funciones:

 scramble <- function(x) x[sample(nrow(x)), ] subscramble <- function(x, condition) { scramble(subset(x, condition)) } subscramble(mtcars, cyl == 4) 

Esto devuelve el error:

Error en eval (expr, envir, enclos): no se encuentra el objeto 'cyl'

porque R ya no "sabe" dónde encontrar el objeto llamado 'cyl'. También señala las cosas realmente extrañas que pueden suceder si por casualidad hay un objeto llamado 'cyl' en el entorno global:

 cyl <- 4 subscramble(mtcars, cyl == 4) cyl <- sample(10, 100, rep = T) subscramble(mtcars, cyl == 4) 

(Correrlos y ver por ti mismo, es bastante loco.)

También [ es más rápido:

 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