如何更高效地基于另一列对数据列进行因子化与重排序?
简洁实现基于另一列重排序因子的方案
你的需求是根据label_day的指定顺序(week_order)来排序legend_text,从而让ggplot的柱状图按该顺序展示。现有代码可行,但可以通过更紧凑的方式实现,避免中间变量和多次数据转换:
方案1:用forcats::fct_reorder直接关联排序
借助forcats包的fct_reorder函数,直接根据label_day在week_order中的位置来重排legend_text,无需提前排序整个数据集:
library(tidyverse) week_order <- c('Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Mon', 'Tue' ) df <- tibble(metric = c(0, 8, 12, 18, 6, 12, 20), label_day = c('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'), legend_text = c('Off', 'ReEntry', 'Strength', 'Match 1', 'Recovery', 'Activation', 'Match 2')) # 一步完成legend_text的因子重排 df <- df |> mutate(legend_text = fct_reorder(legend_text, match(label_day, week_order))) # 绘图 ggplot(df, aes(x = legend_text, y = metric)) + geom_col()
方案2:直接生成对应顺序的levels
如果不想依赖forcats,可以直接通过week_order匹配label_day,提取对应的legend_text作为因子水平:
library(tidyverse) week_order <- c('Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Mon', 'Tue' ) df <- tibble(metric = c(0, 8, 12, 18, 6, 12, 20), label_day = c('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'), legend_text = c('Off', 'ReEntry', 'Strength', 'Match 1', 'Recovery', 'Activation', 'Match 2')) # 直接生成按week_order排序的legend_text水平 df <- df |> mutate(legend_text = factor(legend_text, levels = legend_text[match(week_order, label_day)])) # 绘图 ggplot(df, aes(x = legend_text, y = metric)) + geom_col()
这两种方案都省去了先arrange数据集、提取中间变量legend_text_order的步骤,直接通过向量匹配或因子重排函数完成需求,代码更紧凑清晰。
内容的提问来源于stack exchange,提问作者seansteele
相关产品推荐
相关产品推荐

