r - 如果我已经有 y 刻度,则用逗号(和 K?MM?)格式化 ggplot2 轴标签

我正在尝试为 ggplot 图表的 y 轴标签格式化成本和收入(均以千计)和印象数(以百万计)数据。

我的绘图从 31 天前运行到“昨天”,并为 ylim(c(min,max)) 选项使用该期间的最小值和最大值。仅显示成本示例,

library(ggplot2)
library(TTR)

set.seed(1984)

#make series
start <- as.Date('2016-01-01')
end <- Sys.Date()

days <- as.numeric(end - start)

#make cost and moving averages
cost <- rnorm(days, mean = 45400, sd = 11640)
date <- seq.Date(from = start, to = end - 1, by = 'day') 
cost_7 <- SMA(cost, 7)
cost_30 <- SMA(cost, 30)

df <- data.frame(Date = date, Cost = cost, Cost_7 = cost_7, Cost_30 = cost_30)


# set parameters for window
left <- end - 31
right <- end - 1

# plot series
ggplot(df, aes(x = Date, y = Cost))+
geom_line(lwd = 0.5) +
geom_line(aes(y = Cost_7), col = 'red', linetype = 3, lwd = 1) +
geom_line(aes(y = Cost_30), col = 'blue', linetype = 5, lwd = 0.75) +
xlim(c(left, right)) + 
ylim(c(min(df$Cost[df$Date > left]), max(df$Cost[df$Date > left]))) +
xlab("")

我想 a) 想在 y 轴上用逗号表示成千上万,b) 就像这些数字的缩写,用“K”表示千或用“MM”表示数百万。我意识到 b) 可能是一项艰巨的任务,但目前 a) 无法通过

完成

ggplot(...) + ... + ylim(c(min, max)) + scale_y_continuous(labels = comma)

因为抛出以下错误:

## Scale for 'y' is already present. Adding another scale for 'y', which
## will replace the existing scale.

我尝试将 scale_y_continuous(labels = comma) 部分放在 geom_line() 层之后(会引发上述错误)或所有 ggplot 的末尾层,它覆盖了我在 ylim 调用中的限制,然后抛出上面的错误,无论如何。

有什么想法吗?

最佳答案

对于逗号格式,您需要为 label=comma 包含 scales 库。您讨论的“错误”实际上只是一个警告,因为您同时使用了 ylimscale_y_continuous。第二个调用覆盖第一个。您可以改为在对 scale_y_continuous 的一次调用中设置限制并指定逗号分隔的标签:

library(scales)

ggplot(df, aes(x = Date, y = Cost))+
  geom_line(lwd = 0.5) +
  geom_line(aes(y = Cost_7), col = 'red', linetype = 3, lwd = 1) +
  geom_line(aes(y = Cost_30), col = 'blue', linetype = 5, lwd = 0.75) +
  xlim(c(left, right)) + 
  xlab("") +
  scale_y_continuous(label=comma, limits=c(min(df$Cost[df$Date > left]), 
                                           max(df$Cost[df$Date > left])))

另一种选择是在绘图之前将您的数据融合为长格式,这样可以减少所需的代码量并简化美学映射:

library(reshape2)

ggplot(melt(df, id.var="Date"), 
       aes(x = Date, y = value, color=variable, linetype=variable))+
  geom_line() +
  xlim(c(left, right)) + 
  labs(x="", y="Cost") +
  scale_y_continuous(label=comma, limits=c(min(df$Cost[df$Date > left]), 
                                           max(df$Cost[df$Date > left])))

无论哪种方式,要将 y 值以千或百万表示,您可以将 y 值除以 1,000 或 1,000,000。我在下面使用了 dollar_format() ,但我认为如果您使用 unit_format (根据@joran 的建议),您还需要除以适当的 10 次方。例如:

div=1000

ggplot(melt(df, id.var="Date"), 
       aes(x = Date, y = value/div, color=variable, linetype=variable))+
  geom_line() +
  xlim(c(left, right)) + 
  labs(x="", y="Cost (Thousands)") +
  scale_y_continuous(label=dollar_format(),
                     limits=c(min(df$Cost[df$Date > left]), 
                              max(df$Cost[df$Date > left]))/div)

如果需要,使用 scale_color_manualscale_linetype_manual 设置自定义颜色和线型。

https://stackoverflow.com/questions/37713351/

相关文章:

javascript - 在 JavaScript 中将十六进制数字格式化为短 UUID

python - 在 Python 中格式化电话号码的最佳方法是什么?

django - 是否有 django 模板过滤器来显示百分比?

c# - 用年份格式化 TimeSpan

r - 如何删除数字 R 变量中的前导 "0."

android - 在 Android 的 textview [ Html.fromhtml() ]

html - 在每个标记属性上换行并在 Visual Studio HTML 代码编辑器中保持对齐

intellij-idea - 在 PyCharm 中用换行符包装注释

c# - 您如何将 { 和 } 放入格式字符串中

postgresql - 如何将 "1 day 01:30:00"之类的间隔转换为 "25:30:0