¿Por qué es `[` mejor que `subconjunto`?
Cuando necesito filtrar un dato.frame, es decir, extraer filas que cumplen ciertas condiciones, prefiero usar la función 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:{[12]]}
Creo 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 la declaración
subset
anterior está haciendo.Porque las columnas pueden ser referidas como variables en el
select
expresión, puedo guardar algunas pulsaciones. En mi ejemplo anterior, solo tenía que escribirairquality
una vez consubset
, pero tres veces con[
.
Así que estaba viviendo feliz, usando subset
en todas partes porque es más corto y lee mejor, incluso abogando por su belleza a mis compañeros codificadores R. Pero ayer mi mundo se rompió. Al leer la documentación subset
, noto esta sección:
Advertencia
Esta es una función de conveniencia diseñada para su uso interactivo. Para la programación es mejor usar 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 interactivamente"? Sé lo que es una sesión interactiva, a diferencia de un script ejecutado en modo BATCH, pero no veo qué diferencia debería hacer.
Entonces, podría por favor explique " la evaluación no estándar del subconjunto de argumentos" y por qué es peligroso, tal vez proporcione un ejemplo?
2 answers
Esta pregunta fue respondida bien en los comentarios de @James, señalando una excelente explicación de Hadley Wickham de los peligros de subset
(y funciones similares) [aquí] . ¡Ve a leerlo!
Es una lectura algo larga, por lo que puede ser útil registrar aquí el ejemplo que Hadley usa que aborda más directamente la pregunta de "¿qué puede salir mal?":
Hadley sugiere el siguiente ejemplo: supongamos que queremos subconjuntos y luego reordenar un marco de datos usando lo siguiente 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) : object 'cyl' not found
Porque R ya no "sabe" dónde encontrar el objeto llamado 'cyl'. También señala las cosas verdaderamente 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)
(Ejecutarlos y ver por ti mismo, es bastante loco.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-06 02:46:49
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-05 15:48:23