R语言 什么时候使用“with”功能,为什么它很好?

vhmi4jdf  于 2023-11-14  发布在  其他
关注(0)|答案(2)|浏览(149)

使用with()的好处是什么?在帮助文件中,它提到它在从数据创建的环境中计算表达式。这样做的好处是什么?创建一个环境并在那里计算它比在全局环境中计算它更快吗?或者还有什么我遗漏的吗?

6gpjuf90

6gpjuf901#

with是没有data参数的函数的 Package 器

有许多函数可以处理数据框,并接受data参数,这样您就不需要在每次引用列时重新键入数据框的名称。例如,lmplot.formulasubsettransform,以及主要的dplyr函数,如mutatesummarize
with是一个通用的 * Package 器 *,让你可以像使用数据参数一样使用任何函数,这样你就可以在不使用$的情况下引用列。
使用mtcars数据集,我们可以在使用或不使用数据参数的情况下拟合模型:

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

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

字符串
然而,如果(出于某种奇怪的原因)我们想找到cyl + disp + wtmean,就会出现问题,因为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() Package 在with(data, foo(...))中可以让我们使用任何函数foo *,就像 * 它有一个data参数一样-也就是说我们可以使用不带引号的列名,防止重复的data_name$column_namedata_name[, "column_name"]

with的使用方法

在R控制台和R脚本中,您可以随时使用with来保存输入并使代码更清晰。您需要为单个命令重新输入数据框名称的频率越高(数据框名称越长!),使用with的好处就越大。
另外请注意,with并不限于 Dataframe 。从?with开始:
对于默认的with方法,它可以是一个环境、一个列表、一个 Dataframe ,或者是一个整数,就像sys.call一样。
我不经常使用环境,但当我这样做时,我发现with非常方便。

当您只需要一行的结果片段时

正如@Rich Scriven在评论中建议的那样,当你需要使用像rle这样的结果时,with非常有用。如果你只需要一次结果,那么他的例子with(rle(data), lengths[values > 1])可以让你匿名使用rle(data)结果。

何时避免with

data参数为 * 时

很多函数都有一个data参数,当你调用它的时候,它不仅仅是为了简化语法。(如lm),以及许多其他(ggplot!)使用提供的data做了很多事情。如果使用with * 而不是data参数,您将限制可用的功能。如果有data参数,请使用data参数,而不是with

添加环境

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

在包中

不要在R包中使用withhelp(subset)中有一个警告,它也适用于with

警告这是一个交互式的方便函数。对于编程来说,最好使用标准的子集函数,如[,特别是参数子集的非标准评估可能会产生意想不到的后果。

如果你使用with构建一个R包,当你检查它时,你可能会得到关于使用没有可见绑定的变量的警告或注解。这将使该包不能被CRAN接受。

with的替代方案

不要使用attach

许多(大多是过时的)R教程使用attach通过使列可被全局环境访问来避免重新输入 Dataframe 名称。attach is widely considered to be bad practice and should be avoided。附加的主要危险之一是,如果单独修改数据列,它们可能会变得不同步。with避免了这个陷阱,因为它一次只调用一个表达式。有很多,很多关于Stack Overflow的问题,新用户在使用旧教程时遇到了因为attach而产生的问题。简单的解决方案总是 * 不要使用attach *。

一直使用with似乎太重复了

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

q3qa4bjr

q3qa4bjr2#

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

with(mtcars, plot(wt, qsec))

字符串
而不是

plot(mtcars$wt, mtcars$qsec)


前者在mtcars Dataframe 中查找wtqsec

plot(qsec~wt, data = mtcars)


更适合于plot或其他接受data=参数的函数。

相关问题