You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ggplot2的fct_reorder()中使用NSE复用不同数据框绘图

在ggplot2的fct_reorder()中使用非标准求值(NSE)批量生成图表

我来帮你搞定这个问题!要在fct_reorder()里用NSE实现重复绘图,核心是用tidyverse的curly curly运算符({{ }}),它能帮你把传入的参数动态映射到数据框的列上,完美适配批量场景。

第一步:整理示例数据

先把你提供的示例数据转换成可直接复用的格式:

library(tibble)

travel_data <- tribble(
  ~travel_time_br30, ~travel_time_br30_int, ~time_reduction, ~shift, ~not_shift, ~total,
  "0-30", 0, 10, 2780, 3268, 6048,
  "0-30", 0, 20, 2779, 3269, 6048,
  "0-30", 0, 30, 2984, 3064, 6048,
  "0-30", 0, 40, 3211, 2837, 6048,
  "30-60", 30, 10, 2139, 2007, 4146,
  "30-60", 30, 20, 2159, 1987, 4146,
  "30-60", 30, 30, 2363, 1783, 4146,
  "30-60", 30, 40, 2478, 1668, 4146 # 补全缺失的not_shift值
)

第二步:用NSE写可复用的绘图函数

我们定义一个函数,接受数据框和要用来排序的列作为参数,用{{ }}在fct_reorder()和绘图映射中引用参数:

library(ggplot2)
library(forcats)
library(dplyr)
library(stringr)

plot_travel <- function(data, sort_col) {
  data %>%
    ggplot(aes(
      # 用{{ }}动态传入排序列,让fct_reorder识别数据框中的列
      x = fct_reorder(travel_time_br30, {{ sort_col }}),
      y = {{ sort_col }}
    )) +
    geom_col(fill = "#2E86AB") +
    labs(
      x = "Travel Time Range",
      # 自动生成轴标签和标题,不用手动修改
      y = str_to_title(rlang::as_label(enquo(sort_col))),
      title = str_glue("Travel Time vs {str_to_title(rlang::as_label(enquo(sort_col)))}")
    ) +
    theme_minimal()
}

第三步:批量生成图表

现在你只需要传入不同的列名,就能快速生成对应图表:

# 生成针对shift列的图表
plot_shift <- plot_travel(travel_data, shift)

# 生成针对not_shift列的图表
plot_not_shift <- plot_travel(travel_data, not_shift)

# 生成针对total列的图表
plot_total <- plot_travel(travel_data, total)

# 查看其中一个图表(比如shift的)
print(plot_shift)

扩展:支持降序排序

如果需要按降序排序,只需要给函数加一个参数,在fct_reorder()中传入.desc参数:

plot_travel <- function(data, sort_col, desc = FALSE) {
  data %>%
    ggplot(aes(
      x = fct_reorder(travel_time_br30, {{ sort_col }}, .desc = desc),
      y = {{ sort_col }}
    )) +
    geom_col(fill = "#2E86AB") +
    labs(
      x = "Travel Time Range",
      y = str_to_title(rlang::as_label(enquo(sort_col))),
      title = str_glue("Travel Time vs {str_to_title(rlang::as_label(enquo(sort_col)))} ({ifelse(desc, 'Descending', 'Ascending')})")
    ) +
    theme_minimal()
}

# 降序排序的示例
plot_shift_desc <- plot_travel(travel_data, shift, desc = TRUE)

原理说明

{{ sort_col }}是tidyverse NSE的核心语法,它会把你传入的参数(比如shift)“解引用”成数据框中的实际列,让fct_reorder()和ggplot能正确识别。而rlang::as_label(enquo(sort_col))则是把传入的参数转换成字符串,用来动态生成标题和轴标签,让函数更灵活。

内容的提问来源于stack exchange,提问作者HSJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:02:20