R中的点是什么意思 - 个人偏好,命名约定或更多?

时间:2011-09-23 08:51:28

标签: r coding-style naming-conventions plyr

我(可能)在这里不是指“所有其他变量”,意思是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是如此功能,以至于我错过了以前很久以前完成的技巧。

3 个答案:

答案 0 :(得分:104)

函数名称中的点可以表示以下任何一项:

  • 什么都没有
  • S3方法中方法和类之间的分隔符
  • 隐藏功能名称

可能含义

1。什么都没有

除了data.frame之外,data中的点不会将frameplot分开。

2。在S3方法中分离方法和类

plot.lm是通用S3方法的一个示例。因此plot.glmplot(lm(...))是调用plot(glm(...))ls()

时使用的基础函数定义

3。隐藏内部功能

在编写包时,有时在函数名中使用前导点是有用的,因为这些函数在一般视图中有些隐藏。对于程序包来说纯粹是内部的函数有时会使用它。

在此上下文中,“稍微隐藏”只是意味着当您使用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 。通过使用点作为变量的第一个字母,可以更改变量本身的范围。例如:

data.frame

4。其他可能的原因

在Hadley的包中,他使用约定在函数名中使用前导点。这是一种机制,可以尝试确保在解析变量名时,值会解析为用户变量而不是内部函数变量。


并发症

这种不同用途的混搭可能导致非常混乱的情况,因为这些不同的用途都可以混合在同一个函数名中。

例如,要将as.list(..)转换为您使用as.list(iris)

的列表
as.list

在这种情况下,data.frame是一个S3泛型方法,您将as.list.data.frame传递给它。因此,S3函数称为> 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>

{{1}}

答案 1 :(得分:26)

在名称的开头,它的工作方式类似于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方法还是名称中的点。但是,这是一个非常简单的非常强大的机制。

这三个方面的每个方面都有很多,你不应该把我的例子作为好的做法,但它们是基本的差异。

答案 2 :(得分:0)

如果用户定义了.doSomething函数,并且懒于为参数指定所有roxygen文档,那么它将不会在编译软件包时产生错误