为什么是enquo+!!最好替换+评估

2023-12-11

在下面的例子中,为什么我们应该赞成使用f1 over f2?从某种意义上说,它是否更高效?对于习惯使用 R 基础的人来说,使用“substitute + eval”选项似乎更自然。

library(dplyr)

d = data.frame(x = 1:5,
               y = rnorm(5))

# using enquo + !!
f1 = function(mydata, myvar) {
  m = enquo(myvar)
  mydata %>%
    mutate(two_y = 2 * !!m)
}

# using substitute + eval    
f2 = function(mydata, myvar) {
  m = substitute(myvar)
  mydata %>%
    mutate(two_y = 2 * eval(m))
}

all.equal(d %>% f1(y), d %>% f2(y)) # TRUE

换句话说,除了这个特定的例子之外,我的问题是:我可以使用dplyrNSE 具有良好的基础 R 功能,例如替代+评估,或者我真的需要学会喜欢所有这些rlang之所以起作用,是因为它有好处(速度、清晰度、组合性……)?


我想给出一个独立的答案dplyr,因为使用有一个非常明显的优势enquo over substitute。两者都在函数的调用环境中查找以识别赋予该函数的表达式。不同之处在于substitute()只执行一次,同时!!enquo()将正确地遍历整个调用堆栈。

考虑一个简单的函数,它使用substitute():

f <- function( myExpr ) {
  eval( substitute(myExpr), list(a=2, b=3) )
}

f(a+b)   # 5
f(a*b)   # 6

当调用嵌套在另一个函数中时,此功能会中断:

g <- function( myExpr ) {
  val <- f( substitute(myExpr) )
  ## Do some stuff
  val
}

g(a+b)
# myExpr     <-- OOPS

现在考虑使用重写相同的函数enquo():

library( rlang )

f2 <- function( myExpr ) {
  eval_tidy( enquo(myExpr), list(a=2, b=3) )
}

g2 <- function( myExpr ) {
  val <- f2( !!enquo(myExpr) )
  val
}

g2( a+b )    # 5
g2( b/a )    # 1.5

这就是为什么enquo() + !!优于substitute() + eval(). dplyr只是充分利用这一特性来构建一组连贯的 NSE 函数。

UPDATE: rlang 0.4.0引入了一个新的运算符{{(发音为“curly curly”),这实际上是!!enquo()。这使我们能够简化定义g2 to

g2 <- function( myExpr ) {
  val <- f2( {{myExpr}} )
  val
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么是enquo+!!最好替换+评估 的相关文章

  • 闪亮的如何阻止用户访问选项卡?

    我需要阻止用户访问其他选项卡 直到完成某些操作 在这个可重现的示例中 我想阻止用户访问Tab 2直到他按下按钮 该应用程序如下所示 这是该应用程序的代码 library shiny ui lt shinyUI navbarPage tabP
  • R 中第三维的平均值

    R中是否有任何快速方法或内置函数来计算基于第三维的平均值 例如我的数组是 1 1 2 1 1 3 2 2 4 2 1 2 1 11 13 2 12 14 3 1 2 1 21 23 2 22 24 我的输出是 1 2 1 mean 1 11
  • R - 如何为一个图例元素组合 expression()、paste() 和 formatC() 命令?

    我正在努力创造一个美好的传奇 它应该包含希腊字母 mu 我可以使用表达式 一些文字 即 和 mm 以及使用 formatC 格式化的模型系数来完成此操作 我运行没有问题的是要么没有希腊字母 然后我可以使用简单的粘贴命令 leg txt lt
  • Leaflet Map - 第二个多边形使第一层不可点击

    我正在制作美国社区调查数据地图 目前我有一个主要层 如下所示plotMerge incomePerCapita 它运作良好 有一个完全充实的弹出窗口 图像等等 当我添加第二层以提供县和地区边界时 区域边界变得不可单击 似乎被新层掩盖了 如果
  • 如何使用 R / igraph 设置边缘颜色和顶点间距

    我是 R 新手 试图弄清楚如何为我有数据的系统制作社交网络地图 我已经设法从常见问题解答和教程中弄清楚我想做的大部分事情 但我被困在两件事上 如何使画布更大 图表间隔更大 现在已经太挤了 目前 边缘厚度是根据重量设置的 权重代表不同的状态
  • 通过变量分割 data.frame [重复]

    这个问题在这里已经有答案了 我将多个主题的数据存储在一个 CSV 文件中 导入 CSV 文件后 我想将每个参与者的数据拆分到自己的 data frame 中 更确切地说 我想采用下面的示例数据 并创建三个新的 data frames 每个
  • 在开发模式下安装包(R源未编译成Rdb)

    我需要修改R代码在一个R具有 Fortran 绑定的包 当我安装软件包时 我看到存储库目录没有源代码 但是 Rdb而是二进制文件 我看了看devtools包 但我仍然不清楚如何在不编译 R 源部分的情况下安装该包 类似于 python py
  • 在绘图中的所有坐标之间绘制线条

    我有以下数据框 data lt data frame x c 5 1 3 2 5 7 12 y c 5 7 6 1 3 5 6 我可以使用 ggplot 函数绘制这些坐标 并在这些坐标之间画一条线 ggplot data aes x y g
  • 如何找到每个分类变量的连续变量的平均值

    我想在 y 轴上绘制连续的 BMI 在 x 轴上绘制家庭收入的分类变量 并且我希望该图绘制每个类别的平均 BMI 然而 我不知道如何找到家庭收入每个因素的平均体重指数 Dataset nh 5994 total IDs with Obser
  • 在r包中重新导出数据集

    In R包 有可能重新导出函数 这使得很容易回收相同的函数 而不必在不同的包之间重复代码 例如 devtools session info函数是重新导出sessioninfo session info export importFrom s
  • 尝试通过列表递归时,在 R 中出现错误“递归索引在级别 2 失败”

    当我尝试递归遍历图形顶点列表 将它们的值与列表中的一组颜色进行匹配时 出现错误 递归索引在级别 2 失败 我的颜色列表如下 colrs lt list l blue c red n gray50 然后我有一个 igraph 中的顶点列表vs
  • 使用 R 迭代读取、操作多个 Excel 文件并将它们附加到一个数据帧中

    在一个目录下 我有多个具有相似格式的excel文件 您可以从以下位置下载示例文件 here https www dropbox com s ho3visres55kpoy test zip dl 0 我需要 循环文件和read excel
  • 将值添加到 rCharts hPlot 工具提示

    我想通过 rCharts 向标准 Highcharts 工具提示添加一些额外的值 示例代码 require rCharts df lt data frame x c 1 5 y c 5 1 z c A B C D E name c K L
  • 更改列的顺序

    我正在处理一个包含 gt 40 列的大型数据框 我希望能够移动列 而不必指定所有列名称 例如 a lt c 1 5 b lt c 4 3 2 1 1 Percent lt c 40 30 20 10 10 Labels lt c Cat D
  • 如何在 conda 中静音或抑制 gfortran (或 clang?)后端?

    我一直致力于构建一个非常特殊的 conda 环境 专为python and R与串扰使用rpy2 我想出的方法可以安装正确的R包如下 install main environment sh now date T echo Start Tim
  • 使用 gbuffer 在 R 中缓冲(地理)空间点

    我正在尝试缓冲数据集中半径为 100 公里的点 我正在使用该功能gBuffer从包装中rgeos 这是我到目前为止所拥有的 head sampledf postalcode lat lon city province 1 A0A0A0 47
  • 使用facet时ggplot2控制每行的面板数量?

    Is it possible to control the number of panels per row in a ggplot I can only get an equal number of panels on each row
  • 为 RStudio Server 1.0.44 配置日志目录

    我在 CentOS 7 上运行 RStudio Server 1 0 44 根据文档 https support rstudio com hc en us articles 200554766 RStudio Server Applicat
  • 用于更改向量中元素顺序的闪亮小部件

    在很多网站上 您都有一个拖放界面来更改列表中元素的顺序 我正在寻找类似的东西闪亮 我希望用户能够拖放列表中的元素 通过更改顺序来更改优先级 现在我有一个滥用的解决方案selectizeInput 这是可行的 但当选择列表变得更大时 它很快就
  • 如何更改 Quarto pptx 中的字体格式

    我正在 R 中使用 Quarto 创建 pptx 要更改我尝试更改的默认字体格式mainfont范围 但是当我渲染它时 最终的 pptx 文件具有默认字体 Calibri 这是我的文件 YAML 将 Quarto 文件渲染为 pptx 时如

随机推荐