使用 %>% 管道在 dplyr 中链接算术运算符

48

我想了解为什么在 dplyr 或者 magrittr 包中,尤其是链式函数 %>% 与基本运算符 +-*/ 有些问题。

链式操作将前一个语句的输出作为下一个语句的第一个参数输入:

1:10 %>% sum
# [55]

那么为什么这不起作用呢?

1:10 %>%  *2 %>% sum
1:10 %>% .*2 %>% sum

我也发现以下语法可以用于加减,但不能用于乘除。为什么呢?

1:10 %>% +(2) # works OK
1:10 %>% *(2) # nope...

那么,即使要在数据框上执行*2操作,我也应该写一个匿名函数吗?

1:10 %>% (function(x) x*2) %>% sum

谢谢,我在其他SO的问题中找不到答案。


6
иҝҷйҮҢеә”иҜҘдҪҝз”ЁmagrittrеҢ…иҖҢдёҚжҳҜdplyrгҖӮdplyrд»…з”ЁдәҺеӨ„зҗҶж•°жҚ®жЎҶпјҢиҖҢз®ЎйҒ“иҝҗз®—з¬ҰпјҲ%>%пјүжңҖеҲқжқҘиҮӘmagrittrгҖӮ - talat
2
正常添加它们就可以了吗? - stanekam
4
此行为的解释:这里只能使用加减号,因为解析器将它们视为一元加和减运算符,例如 -2。所以这是有效的语法。因此,它在这里进行了解析,然后magrittr开始将评估操纵成二元的 "-"(x, 2) 表达式。没有一元的“*”或“/”函数,所以这些操作会失败。一旦被引用,它们再次成为有效的语法,相应的函数也就被获取了。 - Spacedman
最后我补充一点,这种做法同样适用于测试运算符,如'>','=='。 - agenis
4个回答

66

用反引号或引号将运算符括起来,事情应该按预期工作:

1:10 %>%  `*`(2) %>% sum
# [1] 110

1:10 %>%  `/`(2) %>% sum
# [1] 27.5

11
最好使用反引号来引用,因为它更清楚地区分了非语法函数名称和字符串。在我看来,"+"(1,3) 能够正常工作是历史遗留问题。 - hadley

48

或者使用magrittr包中的Aliases,例如:

1:10 %>% multiply_by(2)
# [1]  2  4  6  8 10 12 14 16 18 20

1:10 %>% add(2)
# [1]  3  4  5  6  7  8  9 10 11 12

Aliases 包括布尔运算符、提取/替换和算术运算符的 '单词'


3

我想分享一下magrittr文档,这样你就可以看到所有的选项!

当前实现的别名有...

extract `[`
extract2    `[[`
inset   `[<-`
inset2  `[[<-`
use_series  `$`
add `+`
subtract    `-`
multiply_by `*`
raise_to_power  `^`
multiply_by_matrix  `%*%`
divide_by   `/`
divide_by_int   `%/%`
mod `%%`
is_in   `%in%`
and `&`
or  `|`
equals  `==`
is_greater_than `>`
is_weakly_greater_than  `>=`
is_less_than    `<`
is_weakly_less_than `<=`
not (`n'est pas`)   `!`
set_colnames    `colnames<-`
set_rownames    `rownames<-`
set_names   `names<-`
set_class   `class<-`
set_attributes  `attributes<-`
set_attr    `attr<-`

1
作为对上面答案的补充,在编程中使用magrittr包中的Aliases非常方便,例如: magrittr的可管道操作符替换
操作符 功能替代
x * y x %>% multiply_by(y)
x ^ y x %>% raise_to_power(y)
x[y] x %>% extract(y)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接