subconjuntos - teoria de conjuntos operaciones
¿Por qué al subconjunto no le importa el argumento del subconjunto perdido para los marcos de datos? (1)
tl; dr : la función de subset
llama a diferentes funciones (tiene diferentes métodos) según el tipo de objeto al que se alimenta. En el ejemplo anterior, subset(numbers, )
usa subset.default
mientras que subset(frame, )
usa subset.data.frame
.
R tiene un par de sistemas orientados a objetos integrados. El más simple y más común se llama S3. Este estilo de programación OO implementa lo que Wickham llama un "OO de función genérica". Bajo este estilo de OO, un objeto llamado función genérica mira la clase de un objeto y luego aplica el método apropiado al objeto. Si no existe un método directo, siempre hay un método predeterminado disponible.
Para tener una mejor idea de cómo funciona S3 y los otros sistemas OO, puede verificar la parte relevante del sitio Advanced R. El procedimiento para encontrar el método apropiado para un objeto se conoce como despacho del método. Puede leer más sobre esto en el archivo de ayuda ?UseMethod
.
Como se indicó en la sección Detalles del ?subset
La función del subset
"es una función genérica". Esto significa que el subset
examina la clase del objeto en el primer argumento y luego utiliza el envío de métodos para aplicar el método apropiado al objeto.
Los métodos de una función genérica están codificados como
<nombre de función genérico>. <nombre de clase>
y se puede encontrar usando methods(<generic function name>)
. Para el subset
, obtenemos
methods(subset)
[1] subset.data.frame subset.default subset.matrix
see ''?methods'' for accessing help and source code
lo que indica que si el objeto tiene una clase data.frame, el subset
llama al subset.data.frame
del método (función). Se define de la siguiente manera:
subset.data.frame
function (x, subset, select, drop = FALSE, ...)
{
r <- if (missing(subset))
rep_len(TRUE, nrow(x))
else {
e <- substitute(subset)
r <- eval(e, x, parent.frame())
if (!is.logical(r))
stop("''subset'' must be logical")
r & !is.na(r)
}
vars <- if (missing(select))
TRUE
else {
nl <- as.list(seq_along(x))
names(nl) <- names(x)
eval(substitute(select), nl, parent.frame())
}
x[r, vars, drop = drop]
}
Tenga en cuenta que si falta el argumento del subconjunto, las primeras líneas
r <- if (missing(subset))
rep_len(TRUE, nrow(x))
producir un vector de TRUE de la misma longitud que data.frame, y la última línea
x[r, vars, drop = drop]
introduce este vector en el argumento de la fila, lo que significa que si no incluyó un argumento de subconjunto, la función de subset
devolverá todas las filas del marco de datos.
Como podemos ver en el resultado de la llamada a methods
, el subset
no tiene métodos para vectores atómicos. Esto significa, como su error
Error en subset.default (números,)
que cuando aplica un subset
a un vector, R llama al método subset.default
que se define como
subset.default
function (x, subset, ...)
{
if (!is.logical(subset))
stop("''subset'' must be logical")
x[subset & !is.na(subset)]
}
La función subset.default
arroja un error con stop
cuando falta el argumento del subconjunto.
Normalmente me pregunto de dónde vienen los errores misteriosos, pero ahora mi pregunta es de dónde proviene una misteriosa falta de error.
Dejar
numbers <- c(1, 2, 3)
frame <- as.data.frame(numbers)
Si escribo
subset(numbers, )
(así que quiero tomar un subconjunto pero olvidar especificar el subconjunto-argumento de la función de subconjunto) entonces R me recuerda (como debería):
Error en subset.default (números,):
argumento "subconjunto" no se encuentra, por defecto
Sin embargo, cuando escribo
subset(frame,)
(Así que lo mismo con un data.frame
lugar de un vector), no da un error sino que simplemente devuelve el dataframe (completo).
¿Que esta pasando aqui? ¿Por qué no recibo mi mensaje de error bien merecido?