有没有一种更快的方法来根据另一列中的水平来因子化和重新调整列?

huangapple go评论75阅读模式
英文:

Is there a quicker way to factor and relevel a column based on the levels in another column?

问题

你的代码如下所示可以运行,但我觉得有一种更快的方法来实现这个,但我不知道有没有更好的函数。当我在论坛上搜索基于另一列进行重新分级时,我只能找到关于factor(metric, levels = c(...)的答案 - 这是通过一系列调用完成的 - 但我觉得有一种更优雅的解决方案。

# 我想在ggplot中显示的星期顺序
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'))

# 将`label_day`转换为因子,并根据`week_order`排序
df <- df %>%
  mutate(label_day = factor(label_day, levels = week_order)) %>%
  arrange(label_day)

# 有没有更优雅的方法来做这个? -------------------------------------------------------
# 现在df已经按正确顺序排列,提取`legend_text`的顺序以在ggplot中使用
legend_text_order <- df %>%
  distinct(legend_text) %>%
  pull()

# 将`legend_text`转换为因子,并根据`legend_text_order`排序
df <- df %>%
  mutate(legend_text = factor(legend_text, levels = legend_text_order))
# ------------------------------------------------------------------------------------

# 绘图
ggplot(df, aes(x = legend_text, y = metric)) +
  geom_col()

希望这有助于你更优雅地完成相同的任务。

英文:

My code below works, but I feel like I'm missing a way to do this quicker (ie I don't know a better function). When I search forums for relevel based on another column all I am given are answers around factor(metric, levels = c(...) - which I've done through a series of calls - but I feel like there is a more elegant solution.

# Order of the week I would like to display in ggplot
week_order &lt;- c(&#39;Wed&#39;, &#39;Thu&#39;, &#39;Fri&#39;, &#39;Sat&#39;, &#39;Sun&#39;, &#39;Mon&#39;, &#39;Tue&#39; )

# Data
df &lt;- tibble(metric = c(0, 8, 12, 18, 6, 12, 20),
                  label_day = c(&#39;Mon&#39;, &#39;Tue&#39;, &#39;Wed&#39;, &#39;Thu&#39;, &#39;Fri&#39;, &#39;Sat&#39;, &#39;Sun&#39;),
                  legend_text = c(&#39;Off&#39;, &#39;ReEntry&#39;, &#39;Strength&#39;, &#39;Match 1&#39;, &#39;Recovery&#39;, &#39;Activation&#39;, &#39;Match 2&#39;))

# Change `label_day` into a factor and order based on `week_order` 
df &lt;- df |&gt;
  mutate(label_day = factor(label_day, levels = week_order)) |&gt;
  arrange(label_day)

# Is there a more elegant way to do this ? -------------------------------------------------------
# Now that the df is in the correct order, pull out the order that `legend_text` is in to use in ggplot
legend_text_order &lt;- df |&gt;
  distinct(legend_text) |&gt;
  pull()

# Change `legend_text` into a factor and order based on `legend_text_order` 
df &lt;- df |&gt;
  mutate(legend_text = factor(legend_text, levels = legend_text_order))
#-------------------------------------------------------------------------------------------------

# Plot
ggplot(df, aes(x = legend_text, y = metric)) +
  geom_col()

答案1

得分: 1

你可以在一个管道中完成所有操作:

df <- df %>%
  mutate(label_day = factor(label_day, levels = week_order)) %>%
  arrange(label_day) %>%
  mutate(legend_text = factor(legend_text, levels = unique(legend_text)))

而且由于你实际上不需要将 label_day 保持为因子,只需使用它的顺序来排列数据集,你可以进一步简化它:

df <- df %>%
  arrange(factor(label_day, levels = week_order)) %>%
  mutate(legend_text = factor(legend_text, levels = unique(legend_text)))

输出:

有没有一种更快的方法来根据另一列中的水平来因子化和重新调整列?

英文:

You can do it all in one pipe:

df &lt;- df |&gt;
  mutate(label_day = factor(label_day, levels = week_order)) |&gt;
  arrange(label_day) |&gt;
  mutate(legend_text = factor(legend_text, levels = unique(legend_text)))

And as you don't actually need keep label_day as a factor, just use it's order to arrange the dataset, you can shrink it a little further:

df &lt;- df |&gt;
  arrange(factor(label_day, levels = week_order)) |&gt;
  mutate(legend_text = factor(legend_text, levels = unique(legend_text)))

Output:

有没有一种更快的方法来根据另一列中的水平来因子化和重新调整列?

huangapple
  • 本文由 发表于 2023年5月15日 07:19:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76250067.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定