何时使用'功能和它为什么好?

时间:2017-02-16 19:59:02

标签: r syntax keyword

使用with()有什么好处?在帮助文件中,它提到它在从数据创建的环境中评估表达式。这有什么好处?创建环境并在那里评估它是否更快,而不是仅仅在全球环境中评估它?或者还有其他我想念的东西?

2 个答案:

答案 0 :(得分:9)

with是没有data参数

的函数的包装器

有许多函数可以处理数据框并采用data参数,因此每次引用列时都不需要重新键入数据框的名称。 lmplot.formulasubsettransform只是几个例子。

with是一个通用的包装器,可让您使用任何函数,就好像它有一个数据参数一样。

使用mtcars数据集,我们可以使用或不使用data参数来拟合模型:

# this is obviously annoying
mod = lm(mtcars$mpg ~ mtcars$cyl + mtcars$disp + mtcars$wt)

# this is nicer
mod = lm(mpg ~ cyl + disp + wt, data = mtcars)

但是,如果(由于一些奇怪的原因)我们想找到mean的{​​{1}},则会出现问题,因为cyl + disp + wt没有像{{1}这样的数据参数确实。这是mean解决的问题:

lm

with中包含# without with(), we would be stuck here: z = mean(mtcars$cyl + mtcars$disp + mtcars$wt) # using with(), we can clean this up: z = with(mtcars, mean(cyl + disp + wt)) ,我们可以使用任何函数foo() ,就像它有一个with(data, foo(...))参数一样 - 也就是说我们可以使用不带引号的列名称,以防止重复的foodata

何时使用data_name$column_name

以交互方式和R脚本使用data_name[, "column_name"]来保存输入并使代码更清晰。您需要为单个命令重新键入数据框名称的频率越高(数据框名称越长!),使用with的好处就越大。

另请注意,with不限于数据框。来自with

  

对于默认的with方法,这可能是?with中的环境,列表,数据框或整数。

我不经常使用环境,但是当我这样做时,我发现with非常方便。

当您只需要一行结果时

正如@Rich Scriven在评论中建议的那样,sys.call在您需要使用with之类的结果时非常有用。如果您只需要一次结果,那么他的示例with可让您匿名使用rle结果。

何时避免with(rle(data), lengths[values > 1])

rle(data)参数

许多具有with参数的函数使用它不仅仅是在调用它时更简单的语法。大多数建模函数(如data)以及许多其他函数(data!)都使用提供的lm做了很多工作。如果您使用ggplot参数的data 而不是,则会限制您可以使用的功能。 如果存在with参数,请使用data参数,而不是data

添加到环境

在上面的示例中,结果已分配给全局环境(data)。要在列表/环境/数据中进行 分配,您可以使用with。 (在bar = with(...)的情况下,within也很好。)

在包

不要在R包中使用data.framestransform中有一条警告也可以适用于with

  

警告这是一个便于交互使用的便利功能。对于编程,最好使用像help(subset)这样的标准子集函数,特别是参数子集的非标准评估可能会产生意想不到的后果。

如果使用with构建R包,当您检查它时,您可能会收到有关使用没有可见绑定的变量的警告或注释。这将使CRAN无法接受包裹。

[

的替代方案

不要使用with

许多(大多数已过时)R教程使用with来避免通过使全局环境可访问列来重新键入数据框名称。 attach is widely considered to be bad practice and should be avoided。附加的主要危险之一是,如果单独修改数据列,则数据列可能会不同步。 attach避免了这个陷阱,因为它一次调用一个表达式。 Stack Overflow上有很多很多问题,其中新用户遵循旧教程并因attach而遇到问题。简单的解决方案始终不要使用with

始终使用attach似乎过于重复

如果您正在执行许多数据操作步骤,您可能会发现自己使用attach开始每行代码。您可能认为这种重复几乎与不使用with一样糟糕。 with(my_data, ...with包都提供了非重复语法的高效数据操作。我鼓励你学会使用其中一个。两者都有出色的文档。

答案 1 :(得分:5)

当我不想继续输入dataframe$时,我会使用它。例如

with(mtcars, plot(wt, qsec))

而不是

plot(mtcars$wt, mtcars$qsec)

前者在wt data.frame中查找qsecmtcars。当然

plot(qsec~wt, mtcars)

更适合于采用data=参数的情节或其他函数。