使用magrittr的复合管道%<>%似乎分配不正确

问题描述

使用%%管道似乎有些问题。

根据magrittr文档

复合赋值管道运算符%%用于更新值 首先将其配成一个或多个rhs表达式,然后 分配结果。例如,some_object%%foo%>%bar是 等效于some_object %foo%>%bar。肯定是 链中的第一个管道运算符,但它的工作方式类似于%>%。

但是,我看到的行为与此矛盾。这是我的反例(很抱歉,它直接来自我的代码

Temp$IncurralAge <- Temp$IncurralAge %>% round((.-2)/5)*5

完美运行。

Temp$IncurralAge %<>% round((.-2)/5)*5

反而会输出与我相同的输出

Temp$IncurralAge %>% round((.-2)/5)*5

我看不到这里出了什么问题,有人看到我的语法有问题吗?

解决方法

该问题中显示的所有表达式都无法按照该问题似乎相信的方式工作。

R表达式优先级

%...%的优先级高于*,因此在执行*之后执行%>%,因此5的乘法不属于%>的右侧%,但在最后一步中将x %>% round(...)的结果乘以5。有关优先级表,请参见?Syntax

例如,下面的y设置为其平方根,而不是其平方根的两倍,因为y %<>% sqrt首先执行,因为%<>%的优先级高于*,并且只有在分配完成后才能进行乘法。

y <- 1:3
y %<>% sqrt * 2
y

使用点

如果希望避免将其自动插入为第一个参数,则点必须是在RHS上传递的函数的参数-如果该点只是作为其参数之一的表达式的一部分,不算-点仍会插入。

例如,

10 %>% sum(.+2)
## [1] 22

10 %>% sum(.,.+2) # same

使用%>%

x以下或等效地.以下的所有情况下,round的第一个参数是第二个参数,是包含x或点的表达式。在x %>% round(...)

的输出上完成乘以5
x <- 1:10 # assumed input

# these are all equivalent

x %>% round((.-2)/5)*5

round(x,(x-2)/5)*5

x %>% round(.,(.-2)/5)*5

x %>% round((.-2)/5)*5

(x %>% round(.,(.-2)/5)) * 5

大概想要的是这些等效表达式之一:

round((x-2)/5) * 5

x %>% `-`(2) %>% `/`(5) %>% round %>% `*`(5)

x %>% subtract(2) %>% divide_by(5) %>% round %>% multiply_by(5)

x %>% { round((.-2)/5) * 5 }

使用%%

例如,上面的最后两行代码也可以与%<>%一起使用%>%,例如

x %<>% { round((.-2)/5) * 5 }