¿Qué significa el punto en R – preferencia personal, convención de nomenclatura o más?

Estoy (probablemente) NO refiriéndome al “todas las demás variables”, que quiere decir var1~. aquí. Fui señalado a plyr una vez más y miré en mlply y me pregunté por qué los parámetros se definen con un punto mlply como este:

 function (.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .parallel = FALSE) { if (is.matrix(.data) & !is.list(.data)) .data <- .matrix_to_df(.data) f <- splat(.fun) alply(.data = .data, .margins = 1, .fun = f, ..., .expand = .expand, .progress = .progress, .parallel = .parallel) }  

¿De qué sirve eso? ¿Es solo preferencia personal, convención de nombres o más? A menudo, R es tan funcional que echo de menos un truco que hace tiempo se hacía antes.

Un punto en el nombre de la función puede significar cualquiera de los siguientes:

  • nada en absoluto
  • un separador entre método y clase en métodos S3
  • para ocultar el nombre de la función

Posibles significados

1. Nada en absoluto

El punto en data.frame no separa los data del frame , que no sean visualmente.

2. Separación de métodos y clases en métodos S3

plot es un ejemplo de un método S3 genérico. Así, plot.lm y plot.glm son las definiciones de funciones subyacentes que se utilizan al llamar a plot(lm(...)) o plot(glm(...))

3. Para ocultar las funciones internas

Al escribir paquetes, a veces es útil usar puntos iniciales en los nombres de las funciones porque estas funciones están algo ocultas a la vista general. Las funciones que deben ser puramente internas a un paquete a veces usan esto.

En este contexto, “algo oculto” simplemente significa que la variable (o función) no se mostrará normalmente cuando liste un objeto con ls() . Para forzar que ls muestre estas variables, use ls(all.names=TRUE) . Al usar un punto como primera letra de una variable, cambia el scope de la variable en sí. Por ejemplo:

 x <- 3 .x <- 4 ls() [1] "x" ls(all.names=TRUE) [1] ".x" "x" x [1] 3 .x [1] 4 

4. Otras posibles razones

En el paquete plyr de Hadley, usa la convención para usar puntos principales en nombres de funciones. Esto como un mecanismo para tratar de garantizar que al resolver los nombres de las variables, los valores se resuelven en las variables de usuario en lugar de las variables de funciones internas.


Complicaciones

Esta mezcolanza de diferentes usos puede conducir a situaciones muy confusas, porque estos diferentes usos pueden confundirse en el mismo nombre de función.

Por ejemplo, para convertir un data.frame a una lista que utiliza como as.list(..)

 as.list(iris) 

En este caso, as.list es un método genérico S3 y le está pasando un data.frame . Por lo tanto, la función S3 se llama as.list.data.frame :

 > as.list.data.frame function (x, ...) { x <- unclass(x) attr(x, "row.names") <- NULL x }  

Y para algo realmente espectacular, cargue el paquete data.table y mire la función as.data.table.data.frame :

 > library(data.table) > methods(as.data.table) [1] as.data.table.data.frame* as.data.table.data.table* as.data.table.matrix* Non-visible functions are asterisked > data.table:::as.data.table.data.frame function (x, keep.rownames = FALSE) { if (keep.rownames) return(data.table(rn = rownames(x), x, keep.rownames = FALSE)) attr(x, "row.names") = .set_row_names(nrow(x)) class(x) = c("data.table", "data.frame") x }  

Al comienzo de un nombre, funciona como la convención de nombre de archivo UNIX para mantener los objetos ocultos por defecto.

 ls() character(0) .a <- 1 ls() character(0) ls(all.names = TRUE) [1] ".a" 

Puede ser solo un token sin ningún significado especial, no está haciendo nada más que cualquier otro token permitido.

 my.var <- 1 my_var <- 1 myVar <- 1 

Se usa para el despacho del método S3. Entonces, si defino la clase simple "myClass" y creo objetos con ese atributo de clase, las funciones genéricas como print () se enviarán automáticamente a mi método de impresión específico.

 myvar <- 1 print(myvar) class(myvar) <- c("myClass", class(myvar)) print.myClass <- function(x, ...) { print(paste("a special message for myClass objects, this one has length", length(x))) return(invisible(NULL)) } print(myvar) 

Hay una ambigüedad en la syntax para S3, ya que no se puede decir a partir del nombre de una función si se trata de un método S3 o simplemente un punto en el nombre. Pero, es un mecanismo muy simple que es muy poderoso.

Hay mucho más para cada uno de estos tres aspectos, y no debes tomar mis ejemplos como buenas prácticas, pero son las diferencias básicas.

    Intereting Posts