如何在tidyverse的arrange()中遍历列名向量实现排序?
高效使用列名向量在tidyverse的arrange()中排序
当你需要基于列名向量批量指定排序规则(比如统一降序)时,完全不需要手动逐个列写desc(.data[[cols[n]]]),以下两种方法可以高效实现需求:
方法1:使用syms + map + !!!
利用rlang包的符号转换工具,将字符列名转为符号,批量包裹desc后展开为arrange的参数:
library(tidyverse) mpg <- mpg |> slice(1:2) |> select(1:4) cols <- names(mpg)[1:4] mpg_arranged <- mpg |> arrange(!!!map(syms(cols), desc)) mpg_arranged #> # A tibble: 2 × 4 #> manufacturer model displ year #> <chr> <chr> <dbl> <int> #> 1 audi a4 1.8 1999 #> 2 audi a4 1.8 1999
syms(cols):将字符向量转为符号向量,让dplyr识别列名map(syms(cols), desc):给每个列名符号添加降序规则,生成包含desc(manufacturer)、desc(model)等的列表!!!:将列表展开为arrange的独立参数,等价于手动逐个写规则
方法2:使用across(dplyr 1.0.0+)
dplyr 1.0.0及以上版本支持在arrange中使用across,写法更简洁直观:
mpg_arranged <- mpg |> arrange(across(all_of(cols), desc))
all_of(cols):精准匹配字符向量中的列名(避免列名不存在时的模糊匹配警告)across(..., desc):对指定列统一应用desc降序规则
两种方法都能达到和手动指定列排序完全一致的效果,且可以灵活调整排序规则(比如部分列升序部分降序时,只需要修改map或across的函数即可)。
内容的提问来源于stack exchange,提问作者its.me.adam
相关产品推荐
相关产品推荐

