Dấu chấm có ý nghĩa gì trong R - sở thích cá nhân, quy ước đặt tên hoặc hơn thế nữa?


77

Tôi (có thể) KHÔNG đề cập đến ý nghĩa "tất cả các biến khác" như var1~.ở đây. Tôi đã được chỉ đến plyrmột lần nữa và xem xét mlplyvà tự hỏi tại sao các tham số được xác định bằng dấu chấm ở đầu như thế này:

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>

Công dụng của cái đó là gì? Đó chỉ là sở thích cá nhân, quy ước đặt tên hay hơn thế nữa? Thường thì R có nhiều chức năng nên tôi đã bỏ lỡ một thủ thuật đã được thực hiện từ lâu.


6
Câu hỏi hay. Ngoài việc sử dụng các dấu chấm trong tên hàm ( is.na, as.data.frame, ...) là không bình thường trong ngôn ngữ lập trình khác, nhưng tôi thích nó.
TMS


Các purrrgói (purrr.tidyverse.org) bây giờ có thêm một lớp nghĩa như trong ~ .x+1== function(x) x+1.
isomorphismes

1
Vì vậy, nhiều sự nhầm lẫn này có thể được giải quyết nếu bàn phím đưa _chìa khóa trong một điểm reasily thể truy cập (như bạn biết đấy, thay vì một Shoppingchìa khóa ...)
isomorphismes

Câu trả lời:


118

Dấu chấm trong tên hàm có thể có nghĩa là bất kỳ điều nào sau đây:

  • không có gì đâu
  • dấu phân cách giữa phương thức và lớp trong các phương thức S3
  • để ẩn tên hàm

Ý nghĩa có thể

1. Không có gì cả

Dấu chấm trong data.framekhông tách biệt datavới frame, ngoài trực quan.

2. Tách các phương thức và lớp trong các phương thức S3

plotlà một ví dụ về phương pháp S3 chung. Do đó plot.lmplot.glmlà các định nghĩa hàm cơ bản được sử dụng khi gọi plot(lm(...))hoặcplot(glm(...))

3. Để ẩn các chức năng bên trong

Khi viết các gói, đôi khi sử dụng các dấu chấm ở đầu trong tên hàm rất hữu ích vì các hàm này hơi bị ẩn khỏi chế độ xem chung. Các chức năng có nghĩa là hoàn toàn nội bộ của một gói đôi khi sử dụng điều này.

Trong ngữ cảnh này, "hơi bị ẩn" chỉ đơn giản có nghĩa là biến (hoặc hàm) thường sẽ không hiển thị khi bạn liệt kê đối tượng với ls(). Để buộc lshiển thị các biến này, hãy sử dụng ls(all.names=TRUE). Bằng cách sử dụng dấu chấm làm chữ cái đầu tiên của một biến, bạn thay đổi phạm vi của chính biến đó. Ví dụ:

x <- 3
.x <- 4

ls()
[1] "x"

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

x
[1] 3
.x
[1] 4

4. Các lý do có thể khác

Trong Hadley's gói, anh ta sử dụng quy ước sử dụng dấu chấm ở đầu trong tên hàm. Đây là một cơ chế để thử và đảm bảo rằng khi phân giải tên biến, các giá trị sẽ phân giải cho các biến người dùng chứ không phải các biến hàm nội bộ.


Các biến chứng

Việc trộn lẫn các mục đích sử dụng khác nhau này có thể dẫn đến các tình huống rất khó hiểu, bởi vì những mục đích sử dụng khác nhau này có thể bị trộn lẫn trong cùng một tên hàm.

Ví dụ: để chuyển đổi data.framemột danh sách bạn sử dụngas.list(..)

as.list(iris)

Trong trường hợp as.listnày là một phương thức chung S3 và bạn đang chuyển một phương thức data.framecho nó. Do đó, hàm S3 được gọi là as.list.data.frame:

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

Và đối với một cái gì đó thực sự ngoạn mục, hãy tải data.tablegói và xem chức năng 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>

Bạn có nghĩa là gì với "hơi ẩn" ? Dấu chấm không thay đổi phạm vi biến, phải không? Vì vậy, nó ẩn chỉ với nghĩa là người dùng thường không sử dụng dấu chấm ở đầu tên biến, phải không?
TMS

1
nhưng đó không phải là thịt thông thường với "phạm vi". Phạm vi thường được sử dụng dưới dạng toàn cục / cục bộ (đến hàm, gói, ...), không chỉ ẩn trong ls()(nhưng vẫn có thể truy cập được).
TMS

1
Ồ, tôi hiểu ý bạn. Không, hành vi phạm vi đối với x.xgiống nhau. Chúng chỉ xảy ra là các biến khác nhau.
Andrie

3
Tôi chỉ làm điều đó trong plyr, vì bạn muốn phân biệt giữa các đối số cho hàm plyr và các đối số cho hàm mà plyr đang gọi.
hadley 24/09/11

3
plyr cũng có một .chức năng. get(".") ; function (..., .env = parent.frame()) { structure(as.list(match.call()[-1]), env = .env, class = "quoted") }
baptiste

28

Ở phần đầu của tên, nó hoạt động giống như quy ước tên tệp UNIX để giữ các đối tượng ẩn theo mặc định.

ls()
character(0)

.a <- 1

ls()
character(0)

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

Nó có thể chỉ là một mã thông báo không có ý nghĩa đặc biệt, nó không làm gì hơn bất kỳ mã thông báo được phép nào khác.

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

Nó được sử dụng để gửi phương thức S3. Vì vậy, nếu tôi định nghĩa lớp đơn giản "myClass" và tạo các đối tượng với thuộc tính lớp đó, thì các hàm chung chung như print () sẽ tự động gửi đến phương thức in cụ thể của tôi.

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)

Có một sự mơ hồ trong cú pháp cho S3, vì bạn không thể biết từ tên của một hàm liệu đó có phải là một phương thức S3 hay chỉ là một dấu chấm trong tên. Nhưng, đó là một cơ chế rất đơn giản nhưng rất mạnh mẽ.

Có rất nhiều điều khác cho mỗi khía cạnh trong ba khía cạnh này, và bạn không nên coi các ví dụ của tôi là phương pháp hay, nhưng chúng là những điểm khác biệt cơ bản.


3
Tại sao bạn lại muốn ẩn một số đối tượng không phải là toàn cục?
Matt Bannert

3
Bạn cũng có thể xác định biến hoặc hàm dưới dạng một dấu chấm duy nhất! Thích .=1hoặc .(1). Điều đó thực sự kỳ lạ, đặc biệt là trong các biểu thức .*.+.:-)
TMS

0

Nếu người dùng xác định một hàm .doSomething và lười chỉ định tất cả tài liệu roxygen cho các tham số, nó sẽ không tạo ra lỗi khi biên dịch gói

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.