如果我已经有y比例,用逗号(和K?MM?)格式化ggplot2轴标签

d8a*_*nja 25 formatting r 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("")
Run Code Online (Sandbox Code Playgroud)

ggplot输出

我想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.
Run Code Online (Sandbox Code Playgroud)

我已经尝试将该scale_y_continuous(labels = comma)部分放在geom_line()图层之后(抛出上面的错误)或所有ggplot图层的末尾,这会覆盖我在ylim调用中的限制,然后抛出上面的错误,无论如何.

有任何想法吗?

eip*_*i10 31

对于逗号格式,您需要包含scales库label=comma.您讨论的"错误"实际上只是一个警告,因为您使用了两个ylim然后scale_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])))
Run Code Online (Sandbox Code Playgroud)

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

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])))
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,要将y值以千或数百计算,您可以将y值除以1,000或1,000,000.我已经dollar_format()在下面使用了,但是如果你使用的话,我认为你还需要除以10的适当幂unit_format(根据@joran的建议).例如:

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)
Run Code Online (Sandbox Code Playgroud)

如果需要scale_color_manual,scale_linetype_manual可以使用和设置自定义颜色和线型.

在此输入图像描述

  • @ D8Amonk很确定.`label = unit_format(unit ="K")`. (7认同)
  • @ D8Amonk尝试在(b)的**scale**包中查看`unit_format`. (4认同)
  • @ D8Amonk`unit_format`本身调用`逗号`.只需使用`unit_format`即可. (4认同)
  • "那真是令人沮丧的简单." R中的一切都很简单......一旦你知道秘密! (4认同)
  • @joran`unit_format`似乎非常有用; 但是,我注意到`scale_y_continuous(label = unit_format(unit ="m",scale = 1e-6))`会将6,000,000缩写为"6 m".这不是一件大事,但在英国它会[*稍微更常见*](https://english.stackexchange.com/a/149201/141211)使用**`6m`**,中间没有空格. (3认同)
  • @joran @Konrad您可以使用`unit_format`中的`sep`字段来摆脱空间.例如,`unit_format(unit ="M",scale = 1e-6,sep ="")`.见(https://www.rdocumentation.org/packages/scales/versions/0.4.1/topics/unit_format) (3认同)

小智 7

我刚刚找到了解决方案。它不适用于“标签 = 逗号”。请试试这个解决方案:

scale_y_continuous(labels = scales::comma) 它对我很有效。