使用 dplyr 和 lazyeval 进行编程

2024-01-05

我在以保留非标准评估的方式重构 dplyr 时遇到问题。假设我想创建一个始终选择和重命名的函数。

library(lazyeval)
library(dplyr)

df <- data.frame(a = c(1,2,3), f = c(4,5,6), lm = c(7, 8 , 9))

select_happy<- function(df, col){
    col <- lazy(col)
    fo <- interp(~x, x=col)
    select_(df, happy=fo)
}

f <- function(){
    print('foo')
}

select_happy()是根据这个帖子的答案写的当库函数使用非标准评估时重构 R 代码 https://stackoverflow.com/questions/26058182/refactor-r-code-when-library-functions-use-non-standard-evaluation. select_happy()适用于未定义或在全局环境中定义的列名称。但是,当列名也是另一个命名空间中的函数名称时,就会遇到问题。

select_happy(df, a)
#   happy
# 1     1
# 2     2
# 3     3

select_happy(df, f)
#   happy
# 1     4
# 2     5
# 3     6

select_happy(df, lm)
# Error in eval(expr, envir, enclos) (from #4) : object 'datafile' not found

environment(f)
# <environment: R_GlobalEnv>

environment(lm)
# <environment: namespace:stats>

Calling lazy()on f 和 lm 显示了惰性对象的差异,其中 lm 的函数定义出现在惰性对象中,而对于 f 它只是函数的名称。

lazy(f)
# <lazy>
#   expr: f
#   env:  <environment: R_GlobalEnv>

lazy(lm)
# <lazy>
#   expr: function (formula, data, subset, weights, na.action, method = "qr",  ...
#   env:  <environment: R_GlobalEnv>

substitute似乎与 lm 一起工作。

 select_happy<- function(df, col){
     col <- substitute(col) # <- substitute() instead of lazy()
     fo <- interp(~x, x=col)
     select_(df, happy=fo)
}

select_happy(df, lm)
#   happy
# 1     7 
# 2     8
# 3     9

然而读完之后小插图上lazyeval https://cran.r-project.org/web/packages/lazyeval/vignettes/lazyeval.html看起来lazy应该作为更好的替代品substitute。此外,常规的select功能运行得很好。

select(df, happy=lm)
#   happy
# 1     7
# 2     8
# 3     9

我的问题是我该如何写select_happy()以便它能以各种方式发挥作用select()做?我很难理解范围界定和非标准评估。更一般地说,使用 dplyr 进行编程可以避免这些问题和其他问题的可靠策略是什么?

Edit

我测试了 docendo discimus 的解决方案,它效果很好,但我想知道是否有一种方法可以在函数中使用参数而不是点。我认为能够使用也很重要interp()因为您可能想要将输入输入到更复杂的公式中,就像我之前链接到的帖子中一样。我认为问题的核心在于lazy_dots()捕获的表达式与lazy()。我想了解为什么他们的行为不同,以及如何使用lazy()获得与以下相同的功能lazy_dots().

g <- function(...){
    lazy_dots(...)
}

h <-  function(x){
    lazy(x)
}

g(lm)[[1]]
# <lazy>
#   expr: lm
#   env:  <environment: R_GlobalEnv>
h(lm)
# <lazy>
#   expr: function (formula, data, subset, weights, na.action, method = "qr",  ...
#   env:  <environment: R_GlobalEnv> 

甚至改变.follow__symbols to FALSE for lazy()所以它与lazy_dots()不起作用。

lazy
# function (expr, env = parent.frame(), .follow_symbols = TRUE) 
# {
#     .Call(make_lazy, quote(expr), environment(), .follow_symbols)
# }
# <environment: namespace:lazyeval>

lazy_dots
# function (..., .follow_symbols = FALSE) 
# {
#     if (nargs() == 0) 
#         return(structure(list(), class = "lazy_dots"))
#     .Call(make_lazy_dots, environment(), .follow_symbols)
# }
# <environment: namespace:lazyeval>


h2 <-  function(x){
    lazy(x, .follow_symbols=FALSE)
}

h2(lm)
# <lazy>
#  expr: x
#  env:  <environment: 0xe4a42a8>

我只是觉得不知道该做什么。


一种选择可能是进行写入select_happy与标准几乎相同的方式select功能:

select_happy<- function(df, ...){
  select_(df, .dots = setNames(lazy_dots(...), "happy"))
}

f <- function(){
  print('foo')
}

> select_happy(df, a)
  happy
1     1
2     2
3     3
> 
> select_happy(df, f)
  happy
1     4
2     5
3     6
> 
> select_happy(df, lm)
  happy
1     7
2     8
3     9

注意标准的函数定义select函数是:

> select
function (.data, ...) 
{
    select_(.data, .dots = lazyeval::lazy_dots(...))
}
<environment: namespace:dplyr>

另请注意,根据这个定义,select_happy接受选择多个列,但会将任何附加列命名为“NA”:

> select_happy(df, lm, a)
  happy NA
1     7  1
2     8  2
3     9  3

当然,您可以针对这种情况进行一些修改,例如:

select_happy<- function(df, ...){
  dots <- lazy_dots(...)
  n <- length(dots)
  if(n == 1) newnames <- "happy" else newnames <- paste0("happy", seq_len(n))
  select_(df, .dots = setNames(dots, newnames))
}

> select_happy(df, f)
  happy
1     4
2     5
3     6

> select_happy(df, lm, a)
  happy1 happy2
1      7      1
2      8      2
3      9      3
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 dplyr 和 lazyeval 进行编程 的相关文章

  • 在 Shiny 中设置一个绘图缩放以匹配另一个绘图缩放

    我正在尝试使用情节重排获取一个图的 x 轴缩放限制 并将它们应用到 Shiny 中的另一个图 到目前为止 我可以从 plot1 x轴限制 获取相关的plotly relayout数据 将其转换 从数字到日期 并在绘制 plot2 之前将其提
  • 在 R 中进行 Cox 回归后,将预测危险比列添加到数据帧中

    在 R 中运行 Cox PH 回归后 我需要在数据框中添加预测风险比的列 数据框是面板数据 其中 numgvkey 如果公司标识符 和年龄是时间标识符 您可以从此链接下载一小部分日期 https drive google com file
  • 如何生成向量的所有组合[重复]

    这个问题在这里已经有答案了 假设我有 3 个绿球 2 个橙球和 8 个黄球 我想订购它们 鉴于所有相同颜色的球都是相同的 如何生成所有可能的序列 在 R 中 使用gregmisc 我可以 balls lt c orange orange g
  • R从列表中提取数据框,列名中没有前缀

    我在列表中放置了一个数据框 然后 当尝试将其提取回来时 我得到了该数据帧的所有以列表键为前缀的列名称 有没有办法完全按照最初传递的方式提取数据帧 cols lt c column1 Column2 Column3 df1 lt data f
  • 分离并重新附加“tools:rstudio”

    又名玩火 以下不起作用 rstd obj lt as environment tools rstudio detach tools rstudio attach rstd obj name tools rstudio 好吧 它似乎有效 但随
  • 在 mac (iMac OSX ) 终端中远程运行脚本(r 脚本)到其他计算机

    我有一个小示例脚本 script p r 如下所示 打算在终端中运行 usr bin Rscript sink output capture txt mn lt mean 1 10 and so on much longer list of
  • 使用底格里斯河从纬度/经度获取人口普查区

    我有相对较多的坐标 我想获取其人口普查区 除了 FIPS 代码 我知道我可以使用以下命令查找各个纬度 经度对call geolocator latlon 已完成here https stackoverflow com questions 5
  • 将值替换为其各自列的名称

    我有一个数据框 Code 401k CVS 101A true 231N true FD54 true 99JB 85F4 true 我试图用相应的列名称 例如 401k 替换 true 字符值 这是我想要的输出 Code 401k CVS
  • 如何更新条件公式?

    让我直接进入示例 考虑以下等式 frml lt formula y a b x z 使用这样的公式规范 例如和AER ivreg 我想更新这个公式 使其显示为 frml2 lt y a b c x z w 但是 我不确定如何更新条件标志之前
  • 将数据从 R 导出到 Excel

    我试图将从 R 获得的一些结果导出到 Excel 中 但未成功 我尝试过以下代码 write table ALBERTA1 D ALBERTA1 txt sep t write csv ALBERTA1 ALBERTA1 csv your
  • 解析,用三点参数替换

    让我们考虑一个典型的deparse substitute R call f1 lt function u x y print deparse substitute x varU vu varX vx varY vy f1 u varU x
  • 为绘图制作 2D 图例 - 双变量分区统计图

    我一直在玩双变量 choropleth 地图 并且一直在如何创建类似于 2d 图例的问题上陷入困境约书亚 史蒂文斯 http www joshuastevens net cartography make a bivariate chorop
  • 使用 R 进行项目组织 [重复]

    这个问题在这里已经有答案了 可能的重复 统计分析和报告撰写的工作流程 https stackoverflow com questions 1429907 workflow for statistical analysis and repor
  • 为什么这些数字不相等?

    下面的代码显然是错误的 有什么问题 i lt 0 1 i lt i 0 05 i 1 0 15 if i 0 15 cat i equals 0 15 else cat i does not equal 0 15 i does not eq
  • R 中的字符串作为函数参数

    数据框chocolates列出了糖果的类型以及每种糖果的一组评级 ID sweetness filling crash snickers 0 67 0 55 0 40 milky way 0 81 0 53 0 56 我正在编写一个函数 它
  • 使用outer代替expand.grid

    我正在寻找尽可能快的速度并留在基地做该做的事expand grid做 我用过outer为过去类似的目的创建一个向量 像这样的东西 v lt outer letters LETTERS paste0 unlist v lower tri v
  • 表单提交时出现 rvest 错误

    我想从以下网页中抓取数据 https swgoh gg u zozo collection 180 emperor palpatine https swgoh gg u zozo collection 180 emperor palpati
  • 16 位以上整数的计算

    我有两个大整数 两者都超过 16 位 确切地说是 20 位 而且我知道由于双精度浮点运算 我在使用这些数字进行计算甚至将它们存储在变量中 独立于编程语言 时受到限制 不过 我想也许gmp图书馆应该处理它们 但不幸的是它没有 可以计算更大的整
  • ggplot2、R 中的单条形条形图

    我有以下数据和代码 gt ddf var1 var2 1 aa 73 2 bb 18 3 cc 9 gt gt dput ddf structure list var1 c aa bb cc var2 c 73L 18L 9L Names
  • 替换字符串/文本中“从第 n 次到最后一次”出现的单词

    这个问题以前曾被问过 但尚未得到令提问者满意的答案 https stackoverflow com questions 36368712 how to use stringrs replace all function to replace

随机推荐

  • 您可以使用 ffmpeg 流实时插入文件中的文本吗?

    我有这个代码 用于流式传输文件 并将视频某个时间的视频节目名称 name of show 放置在屏幕顶部 屏幕底部则显示节目名称来自 video title txt 并将其放置在屏幕底部 我想要做的是找到一种方法 每隔 1 或 2 分钟 提
  • 如何在 Sonata Media Bundle 中实现多对多关系

    我正在尝试将 SonataMediaBundle 与另一个实体相关联 Products具有多对多关系 架构和关系创建得很好 但是 当我编辑或创建新产品时 我尝试添加一个可以通过媒体库搜索媒体文件的按钮和一个上传新文件的按钮 对于 OneTo
  • 直接链接获取谷歌自定义搜索API密钥?

    我有一个 API 密钥 用于在 json 搜索 API 上进行 Google 自定义搜索查询 如下所示 我需要将客户端发送到一个 URL 每个客户端都可以在其中获取其域的自定义 API 密钥 但是 我不记得用于获取 API 密钥的 URL
  • JavaScript、Node.js:Array.forEach 是异步的吗?

    我有一个关于本地人的问题Array forEachJavaScript 的实现 它的行为是异步的吗 例如 如果我打电话 many many elements forEach function lots of work to do 这会是非阻
  • 在 Mathematica 中使用 $NewSymbol 移动上下文

    我正在玩 NewSymbol试图找到答案这个问题 https stackoverflow com q 6165977 421225 with 文档说 http reference wolfram com mathematica ref 24
  • iOS 上的 javascript 除了在其框架内执行之外,是否还必须由 WebKit 框架下载?

    协议是这样说的 3 3 2 内部使用应用程序不得下载或安装可执行代码 如果所有脚本 代码和解释器都打包在应用程序中并且未下载 则解释的代码只能在应用程序中使用 上述唯一的例外是由 Apple 内置 WebKit 框架下载和运行的脚本和代码
  • TensorFlow 2.0:如何更新张量?

    在 TensorFlow 1 x 中 要更新张量 我会使用tf scatter update 仅更新张量的相关部分 我们如何在 TF 2 0 中做同样的事情 您可以使用tf tensor scatter nd update https ww
  • 在文本中查找相关单词的算法

    我想要一个单词 例如 Apple 并处理一个文本 或者可能更多 我想提出相关术语 例如 处理 Apple 的文档并发现 iPod iPhone Mac 是与 苹果 相关的术语 关于如何解决这个问题有什么想法吗 作为起点 您的问题涉及文本挖掘
  • 如何在C中打印方阵的所有方子矩阵?

    请帮我用C编程语言找到并打印从大到小方阵的所有方阵子矩阵 我写的代码运行错误 int main int mtrx size 8 int mat 8 8 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  • 创建触发器以插入到另一个表中

    我在执行下面的触发器时遇到一些问题 CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL AFTER INSERT ON READING FOR EACH ROW DECLARE varReadNo
  • 使用 JWT 和 OpenID Connect 在微服务中进行客户端身份验证

    我对微服务架构中的身份验证有一些疑问 我现在有一个整体应用程序 我的目标是将应用程序拆分为小型微服务 我最大的问题是身份验证 目前 阅读大量文档后 似乎最好的解决方案是使用 OpenID Connect 对用户进行身份验证以检索 JWT 该
  • 通过 JSch 的 SFTP 抛出错误 4:失败

    我在尝试通过 SFTP 将文件从 Windows 传输到 Unix 服务器时遇到了一个特殊问题 错误 堆栈跟踪 是 4 Failure at com jcraft jsch ChannelSftp throwStatusError Chan
  • 为什么每个请求都会执行passport.serializeUser?

    我使用 Passport js Passport facebook token 通过 Strongloop 的环回框架来保护我的 API 构建 为什么护照反序列化成功后还要再次序列化反序列化的用户 每个请求都会调用 Passport aut
  • mongodb数据目录权限

    早些时候 我将所有 mongodb 数据文件存储在 var lib mongodb 目录中 etc mongodb conf 中的 dbpath 条目是 var lib mongodb 现在我想将数据目录更改为 vol db 所以我创建了目
  • 非泛型类是否可以包含 .NET(C# 或 VB.NET)中的泛型列表?

    我希望有人可以帮助我理解这样的事情是否可能 如何可能 在这种情况下 假设您正在尝试对电子表格或数据库中的网格进行建模 但每列中的数据只能是一种数据类型 示例 第 1 列只能包含整数 我创建了一个通用类来模拟列结构 如下所示 public c
  • 为什么“C”中的索引从零开始?

    为什么 C 中数组的索引从 0 开始 而不是从 1 开始 在C中 数组的名称本质上是一个指针 但请看评论 对内存位置的引用 等等表达式array n 指的是一个内存位置n远离起始元素的元素 这意味着索引被用作偏移量 数组的第一个元素恰好包含
  • 在不使用会话上下文的情况下在 Web 应用程序中保留值

    我有一个 变量 用户可以在 JSP Struts 应用程序中修改该变量 该变量必须在整个 Web 应用程序的会话中保留 他们可能会离开设置和查看该变量的页面 仍然留在应用程序中 并且当他们回来时 他们上次为该变量设置的值应该仍然存在 显而易
  • iOS7-UItableViewCell 以 Grouped 样式显示在表格视图中

    在 iOS7 中 分组表视图的单元格显示为表视图的全宽 更像是普通表视图样式 但在模拟器的设置应用程序中 分组样式看起来不同 对于实现这种类型的单元有什么帮助吗 该解决方案适用于 iOS7 以及以前版本的 iOS 创建自定义 UITable
  • 是否有正则表达式可以返回相同字符的重复匹配?

    使用 NET 正则表达式 假设我有以下文本 哒哒哒哒哒哒 我想测试任何字符的重复次数是否超过 2 次 正则表达式不应返回包含双字母 例如单词 的文本的匹配项 look UPDATE 不要假设输入文本仅包含字母 d 的重复 我想要任何重复的字
  • 使用 dplyr 和 lazyeval 进行编程

    我在以保留非标准评估的方式重构 dplyr 时遇到问题 假设我想创建一个始终选择和重命名的函数 library lazyeval library dplyr df lt data frame a c 1 2 3 f c 4 5 6 lm c