Что означает точка в R - личные предпочтения, соглашение об именах или более? - PullRequest
70 голосов
/ 23 сентября 2011

Я (вероятно) НЕ имею в виду "все остальные переменные", такие как var1~. здесь. Я снова указал на plyr, посмотрел на mlply и удивился, почему параметры определяются с помощью начальной точки следующим образом:

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)
}
<environment: namespace:plyr>

Какая польза от этого? Это просто личные предпочтения, соглашение об именах или больше? Часто R настолько функционален, что я пропускаю трюк, который давно уже был сделан.

Ответы [ 2 ]

104 голосов
/ 23 сентября 2011

Точка в имени функции может означать любое из следующего:

  • вообще ничего
  • разделитель между методом и классом в методах S3
  • , чтобы скрытьимя функции

Возможные значения

1.Ничего вообще

Точка в data.frame не отделяет data от frame, кроме как визуально.

2.Разделение методов и классов в методах S3

plot является одним примером универсального метода S3.Таким образом, plot.lm и plot.glm являются основными определениями функций, которые используются при вызове plot(lm(...)) или plot(glm(...))

3.Чтобы скрыть внутренние функции

При написании пакетов иногда полезно использовать начальные точки в именах функций, поскольку эти функции несколько скрыты от общего вида.Функции, которые должны быть чисто внутренними для пакета, иногда используют это.

В этом контексте «несколько скрытый» просто означает, что переменная (или функция) обычно не отображается, когда вы перечисляете объект с помощью ls().Чтобы заставить ls показывать эти переменные, используйте ls(all.names=TRUE).Используя точку в качестве первой буквы переменной, вы изменяете область действия самой переменной.Например:

x <- 3
.x <- 4

ls()
[1] "x"

ls(all.names=TRUE)
[1] ".x" "x" 

x
[1] 3
.x
[1] 4

4.Другие возможные причины

В пакете Хэдли он использует соглашение для использования начальных точек в именах функций.Это как механизм, позволяющий убедиться, что при разрешении имен переменных значения разрешаются в пользовательских переменных, а не во внутренних переменных функций.


Осложнения

Эта путаница различных применений может привестив очень запутанные ситуации, потому что все эти разные варианты использования могут быть смешаны в одном и том же имени функции.

Например, чтобы преобразовать data.frame в список, который вы используете as.list(..)

as.list(iris)

В этом случае as.list - это общий метод S3, и вы передаете ему data.frame.Таким образом, функция S3 называется as.list.data.frame:

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

И для чего-то действительно впечатляющего загрузите пакет data.table и посмотрите на функцию 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
}
<environment: namespace:data.table>
26 голосов
/ 23 сентября 2011

В начале имени это работает как соглашение об имени файла UNIX, чтобы скрыть объекты по умолчанию.

ls()
character(0)

.a <- 1

ls()
character(0)

ls(all.names = TRUE)
[1] ".a"

Это может быть просто токен без особого значения, он не делает ничего больше, чем любой другой разрешенный токен.

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

Используется для отправки по методу S3. Таким образом, если я определю простой класс «myClass» и создам объекты с этим атрибутом класса, то универсальные функции, такие как print (), автоматически отправят мой конкретный метод печати.

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)

В синтаксисе S3 существует неоднозначность, поскольку по имени функции невозможно определить, является ли это методом S3 или просто точкой в ​​имени. Но это очень простой механизм, который очень мощный.

В каждом из этих трех аспектов есть намного больше, и вы не должны воспринимать мои примеры как хорошую практику, но они являются основными отличиями.

...