R语言 相同的函数,但使用名称%>%会导致与使用名称:=时不同的结果

n3h0vuf2  于 2023-05-04  发布在  其他
关注(0)|答案(1)|浏览(167)

我正在使用@Konrad Rudolph的一个函数,但将其名称从%>%更改为:=,并为相同的调用获得不同的结果。

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

`:=` <- `%>%`

1 %>% .+2 %>% .*3
#[1] 7

1 := .+2 := .*3
#[1] 3

或者具有不同的功能。

`%>%` <- function(lhs, rhs) {
  assign(".", lhs, envir=parent.frame())
  eval(substitute(rhs), parent.frame())
}

`:=` <- `%>%`

1 %>% .+2 %>% .*3
#[1] 7

1 := .+2 := .*3
#[1] 9

为什么我在使用名为:=的函数时会得到其他结果?

db2dz4w8

db2dz4w81#

原因是运算符优先级。我们可以使用lobstr包来查看代码的抽象语法树。

lobstr::ast(1 %>% .+1 %>% .+2)
█─`+` 
├─█─`+` 
│ ├─█─`%>%` 
│ │ ├─1 
│ │ └─. 
│ └─█─`%>%` 
│   ├─1 
│   └─. 
└─2

vs

lobstr::ast(1 := .+1 := .+2)
█─`:=` 
├─1 
└─█─`:=` 
  ├─█─`+` 
  │ ├─. 
  │ └─1 
  └─█─`+` 
    ├─. 
    └─2

因此,当您运行%>%版本时,管道在添加之前发生,但对于:=版本,添加在:=之前发生
如果加上隐式括号,就会发现这两个是等价的
但是您可能期望的行为需要看起来像
但仍然“有效”。而这就是另一个表达式如何分解的
函数的定义方式是,中间项基本上消失了,因为.被外部:=替换,所以内部=没有剩余的.变量
操作顺序在?Syntax帮助页面中定义。如果不更改R源代码本身,就无法更改函数的优先级。虽然页面上没有明确列出,但:=<-具有相同的优先级(在解析器中别名为LEFT_ASSIGN)。

相关问题