Що означає точка в R - особисті уподобання, дотримання імен чи інше?


77

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


6
Гарне питання. Крім того , використання точок в іменах функцій ( is.na, as.data.frame, ...) не прийнято в інших мовах програмування, але мені це подобається.
TMS

Подальше пояснення: stats.stackexchange.com/questions/10712/…
leo9r

purrrПакет (purrr.tidyverse.org) тепер додає ще один шар сенсу , як і в ~ .x+1== function(x) x+1.
ізоморфізми

1
Стільки цієї плутанини можна було б вирішити, якби клавіатури поставили _клавішу в легкодоступному місці (наприклад, знаєте, замість Shoppingклавіші ...)
ізоморфізм

Відповіді:


118

Крапка в назві функції може означати будь-що з наступного:

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

У Хедлі пакунок, він використовує конвенцію для використання перших крапок в іменах функцій. Це як механізм, який намагається забезпечити, щоб при вирішенні імен змінних значення переходили до змінних користувача, а не до змінних внутрішніх функцій.


Ускладнення

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

Наприклад, щоб перетворити 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>

Що ви маєте на увазі під "дещо прихованим" ? Крапка не змінює область змінних, правда? Отже, це приховано лише в тому сенсі, що користувачі зазвичай не використовують крапку на початку імені змінної, так?
TMS

1
але це не те, що звичайне м'ясо з "розмахом". Scope зазвичай використовується з точки зору глобального / локального (для функціонування, упаковки, ...), а не просто приховування ls()(але все ще доступного).
TMS

1
О, я розумію, що ти маєш на увазі. Ні, поведінка області дії для xі .xоднакові. Це просто різні змінні.
Андрі,

3
Я роблю це лише в plyr, тому що ви хочете розрізнити аргументи функції plyr та аргументи функції, яку викликає plyr.
hadley

3
plyr також має .функцію. get(".") ; function (..., .env = parent.frame()) { structure(as.list(match.call()[-1]), env = .env, class = "quoted") }
баптист

28

На початку імені воно працює як 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 чи просто крапкою в назві. Але це дуже простий механізм, який є дуже потужним.

У кожному з цих трьох аспектів є набагато більше, і ви не повинні сприймати мої приклади як добру практику, але вони є основними відмінностями.


3
Чому ви хочете приховати якийсь об’єкт, який і так не є глобальним?
Matt Bannert,

3
Ви також можете визначити змінну або функцію як одну крапку! Подобається .=1або .(1). Це дійсно дивно, особливо у виразах .*.+.:-)
TMS

0

Якщо користувач визначає функцію .doSomething і лінується вказати всю документацію про кисень для параметрів, це не призведе до помилок для компіляції пакету

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.