name - subset vector r
¿Por qué `[` es mejor que `subconjunto`? (2)
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) [here] . Ve a leerlo!
Es una lectura algo larga, por lo que puede ser útil anotar aquí el ejemplo que Hadley usa y que aborda más directamente la pregunta "¿qué puede salir mal?":
Hadley sugiere el siguiente ejemplo: supongamos que deseamos subcontratar y luego reordenar un marco de datos 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): objeto ''cyl'' no encontrado
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)
(Ejecutarlos y ver por ti mismo, es bastante loco.)
Cuando necesito filtrar un data.frame, es decir, extraer filas que cumplan 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:
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 declaración del
subset
anterior.Como las columnas se pueden denominar variables en la expresión de
select
, puedo guardar algunas pulsaciones de tecla. En mi ejemplo anterior, solo tuve que escribirairquality
una vez consubset
, pero tres veces con[
.
Así que vivía feliz, usaba un subset
todas partes porque es más corto y se lee mejor, incluso defendiendo su belleza ante mis compañeros codificadores. Pero ayer mi mundo se rompió. Mientras leo la documentación del subset
, me doy cuenta de esta sección:
Advertencia
Esta es una función de conveniencia para 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 quieren decir los autores?
Primero, ¿qué quieren decir con " para uso interactivo "? 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 explicar " la evaluación no estándar del subconjunto de argumentos " y por qué es peligroso, tal vez proporcionar un ejemplo?
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