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

2 ответа

Решение

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

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

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


осложнения

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

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

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

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

Если пользователь определяет функцию.doSomething и ленится указать всю документацию roxygen для параметров, он не будет генерировать ошибки для компиляции пакета.

Другие вопросы по тегам