Подтвердить что ты не робот

Что означает точка в R - личное предпочтение, соглашение об именовании или более?

Я (возможно) НЕ ссылаюсь на "все остальные переменные", что означает 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 настолько функционально, что я пропускаю трюк, который уже давно был сделан.

4b9b3361

Ответ 1

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

  • ничего вообще
  • разделитель между методом и классом в методах 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. Другие возможные причины

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


Осложнения

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

Например, чтобы преобразовать a 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>

Ответ 2

В начале имени он работает как соглашение с именем файла 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 или просто точка в имени. Но это очень простой механизм, который очень мощный.

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