dplyr/tidyverse中`df <- df %>%`是否有更简短的写法?
dplyr链式操作原地覆盖数据框的简写方案
不用重复写两次数据框名的简写方式是现成的,不需要复杂改造:
- 官方适配的最简写法是用magrittr提供的复合赋值管道
%<>%,加载dplyr时会默认附带这个运算符,不需要额外装包、导包。它的逻辑就是把左侧对象传入右侧管道链运算,最终结果直接赋值回左侧原对象,全程只需要写一次变量名。
原来的冗余写法:
替换后:df <- df %>% mutate(new_col = 'new')
多步处理也可以直接顺延接管道,比如筛选、分组、汇总后直接覆盖原表:df %<>% mutate(new_col = 'new')
注意这个运算符必须放在整套管道链的最开头,放在管道中间位置不会触发对原变量的覆盖赋值。df %<>% filter(value > 0) %>% group_by(category) %>% summarise(avg_val = mean(value)) - 如果你更习惯用R 4.2以上版本自带的原生管道
|>,原生管道没有内置复合赋值能力,可以自己定义一个中缀运算符实现你想要的效果。注意R语法要求自定义中缀运算符必须用%包裹,所以你举例的无百分号的<->写法不符合R语法规则,无法直接实现,定义%<->%的代码如下:
定义完成后就可以用近似你预期的简写:`%<->%` <- function(lhs, rhs) { lhs_var <- deparse(substitute(lhs)) pipeline_res <- eval.parent(bquote(.(substitute(lhs)) |> .(substitute(rhs)))) assign(lhs_var, pipeline_res, envir = parent.frame()) }
用长管道链的时候注意适当加括号明确运算顺序,避免因为自定义运算符优先级问题导致结果出错。df %<->% mutate(new_col = 'new')
提醒:所有直接覆盖原变量的写法,仅适合你明确不需要保留原始数据的场景。处理原始数据前建议先做好备份,避免修改后无法回溯原始值。
内容的提问来源于stack exchange,提问作者sys
相关产品推荐
相关产品推荐

