在使用管道时,LHS自动放置为RHS的第一个参数.这导致两个代码相等的事实:

library(dplyr)
1:10 %>% mean(na.rm = TRUE) # same as...
1:10 %>% mean(., na.rm = TRUE)

我刚遇到这样一种情况,我需要管道自动停止,使用.作为第一个参数(按照要求here).事实上,我never1:10 %>% mean(na.rm = TRUE),也就是说,在使用管道时,我总是显式地向第一个参数提供..因此,我想知道是否有可能防止管道始终自动将.作为第一个参数.

这意味着%>%在默认情况下应该表现为RHS放在花括号中:

1:10 %>% {mean(na.rm = TRUE)} 
# Returns an error since x is missing. This is expected! Again: I
# want %>% not to automatically provide the first argument with .

也有类似的question.但在我的例子中,我希望%>%默认阻止这种行为.

推荐答案

显式替换占位符的管道可以(相当)直接地实现,因为基本R函数substitute实现了占位符的大部分.需要注意的是,substitute需要一个不带引号的表达式,因此我们需要解决这个问题,而且我们显然需要计算结果表达式:

`%>%` = function (lhs, rhs) {
  subst = call('substitute', substitute(rhs), list(. = lhs))
  eval.parent(eval(subst))
}

这里我重复使用了%>%运算符,但如果您担心与‘magrittr’的冲突,您显然可以使用另一个运算符,例如%|%.

1:5 %>% sum(na.rm = TRUE, .) %>% identity()
# Error in identity() : argument "x" is missing, with no default

1:5 %>% sum(na.rm = TRUE, .) %>% identity(.)
# [1] 15

以上用由LHS提供的值在RHS中每次出现.的情况下起作用replacing.也就是说,在判断.is not a name期间.这通常是expecteddesired的语义.然而,这意味着您不能在RHS内分配to .(包括调用替换函数),因为.不是一个名称.

所以像{names(.) = "foo"; .}这样的东西是行不通的.

我们可以用不同的实现来解决这个问题,它不会用LHS替换.,而是在判断RHS的环境中定义.:

`%>%` = function (lhs, rhs) {
  eval_env = new.env(parent = parent.frame())
  eval_env$. = lhs
  eval(substitute(rhs), envir = eval_env)
}

现在我们可以在作业(job)中使用.作为名称:

1 %>% {names(.) = "foo"; .}
# foo
#   1

However,其他一些方法不再起作用,因为我们现在在不同的环境中计算该表达式:

1:5 %>% assign("x", .)
x
# Error: object 'x' not found

…而这did与第一个管道实现一起工作.我们could通过将.直接注入调用环境使其再次工作,但这会扰乱用户环境,我strongly不鼓励这样做.1

相反,如果您想要在管道表达式中调用assign之类的操作,请明确表示要分配给哪个环境(例如,将envir = the_environment传递到assign).


1您可以通过仔细保存用户状态并在事后进行清理来避免扰乱用户环境;但这会导致更复杂(且容易出错)的实现:

`%>%` = function (lhs, rhs) {
  caller = parent.frame()
  
  if (exists('.', envir = caller, inherits = FALSE)) {
    stored_dot = caller$.
    on.exit({caller$. = stored_dot})
  } else {
    on.exit(rm(., envir = caller))
  }
  
  caller$. = lhs
  eval.parent(substitute(rhs))
}

R相关问答推荐

如何提高以键ID为列的表中键查找的效率?

变量计算按R中的行更改

在R中查找每个组不同时间段的总天数

用derrr在R中查找组间的重复项

R s iml包如何处理语法上无效的因子级别?'

汇总数据表中两个特定列条目的值

合并DFS列表并将索引提取为新列

根据1个变量绘制 colored颜色 发散的 map ,由另一个变量绘制饱和度,ggplot2不工作

R-按最接近午夜的时间进行筛选

调换行/列并将第一行(原始数据帧的第一列)提升为标题的Tidyr类似功能?

如何在PDF格式的kableExtra表格中显示管道字符?

我们如何在R中透视数据并在之后添加计算

我将工作代码重构为一个函数--现在我想不出如何传递轴列参数

删除数据帧中特定行号之间的每第三行和第四行

如何提取R中其他字符串和数字之间的字符串?

使用ifElse语句在ggploy中设置aes y值

计算多变量的加权和

将R中对象的CSV数组转换为JSON数组

我有2011-2022年的年度数据.如何计算最低年份和最高年份之间的差额?

从字符串列中的向量中查找第一个匹配的单词