我想用双Y轴构建图。
在图像中,您可以看到我的数据框和图。它是在Excel中完成的,我需要在R中做同样的事情。我尝试使用latticeExtra
库,但是它不显示任何行和框
library(latticeExtra)
obj1 <- xyplot(Q_TY_PAPER ~ PU, df, type = "h")
obj2 <- xyplot(COM_USD ~ PU, df, type = "l")
doubleYScale(obj1, obj2, text = c("obj1", "obj2"))`
你能帮我吗?
这是我想要获取的数据集和图的捕获:
答案 0 :(得分:1)
您需要将数据框一分为二,一个将用于条形图并需要重塑形状,第二个将用于需要缩放的线。
基本上,将在与条形图相同的y轴上绘制该线,但是,我们将添加一个辅助y轴,该第二y轴上的标记对应于该线的“实际”值。
因此,首先,我们需要将值图重新缩放为一条线。就像我们在您的示例中看到的那样,条形图中的值8与该行的值500匹配,我们可以通过应用8/500的比例来重新缩放:
df_line = df[,c("PU","COM_USD")]
df_line$COM_USD_2 = df_line$COM_USD * 8/500
> df_line
PU COM_USD COM_USD_2
1 Client1 464 7.424
2 Client2 237 3.792
3 Client3 179 2.864
4 Client4 87 1.392
5 Client5 42 0.672
6 Client6 27 0.432
7 Client7 10 0.160
对于条形图,我们需要将数据转换为更长的格式,以适应ggplot2
的语法。为此,我们可以使用pivot_longer
包中的tidyr
(已加载tidyverse
):
library(tidyverse)
df_bar <- df %>% select(-COM_USD) %>% pivot_longer(., - PU, names_to = "Variable", values_to = "Value")
# A tibble: 21 x 3
PU Variable Value
<fct> <chr> <dbl>
1 Client1 Q_TY_PAPER 7.1
2 Client1 Q_TY_ONLINE 7.1
3 Client1 CURR 6
4 Client2 Q_TY_PAPER 3.8
5 Client2 Q_TY_ONLINE 3.8
6 Client2 CURR 3.9
7 Client3 Q_TY_PAPER 4.4
8 Client3 Q_TY_ONLINE 4.4
9 Client3 CURR 2.3
10 Client4 Q_TY_PAPER 2.6
# … with 11 more rows
现在,您可以通过执行以下操作来绘制它们:
library(tidyverse)
ggplot(df_bar, aes(x = PU, y = Value))+
geom_bar(aes(fill = Variable), stat = "identity", position = position_dodge(), alpha = 0.8)+
geom_line(data = df_line, aes(x = PU, y = COM_USD_2, group = 1), size = 2, color = "blue")+
scale_y_continuous(name = "Quantity", limits = c(0,8), sec.axis = sec_axis(~(500/8)*., name = "USD"))+
theme(legend.title = element_blank(),
axis.title.x = element_blank())
如您所见,在scale_y_continuous
中,我们设置了第二个轴,该轴的刻度值乘以反向比率(500/8)。这样,它将匹配绘制的线的值。
最后,您得到以下绘图:
数据
PU = paste0("Client",1:7)
COM_USD = c(464,237,179,87,42,27,10)
Q_TY_PAPER = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
Q_TY_ONLINE = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
CURR = c(6.0,3.9,2.3,0.2,0.2,0.1,0)
df = data.frame(PU,COM_USD, Q_TY_PAPER, Q_TY_ONLINE, CURR)
编辑:将长名称作为x轴标签处理
如果客户端的真实数据名称太长,则可以使用此解决方案(Two lines of X axis labels in ggplot)在两行中写入它们。
因此,首先修改PU
变量:
PU = c("Jon Jon", "Bob Bob", "Andrew Andrew", "Henry Henry", "Alexander Alexander","Donald Donald", "Jack Jack")
COM_USD = c(464,237,179,87,42,27,10)
Q_TY_PAPER = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
Q_TY_ONLINE = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
CURR = c(6.0,3.9,2.3,0.2,0.2,0.1,0)
df = data.frame(PU,COM_USD, Q_TY_PAPER, Q_TY_ONLINE, CURR)
然后,我们应用与上述相同的代码:
df_line = df[,c("PU","COM_USD")]
df_line$COM_USD_2 = df_line$COM_USD * 8/500
library(tidyverse)
df_bar <- df %>% select(-COM_USD) %>% pivot_longer(., - PU, names_to = "Variable", values_to = "Value")
但是对于绘图,您可以使用scale_x_discrete
并通过添加labels
来指定\n
来表示R以在多行上写x标签:
ggplot(df_bar, aes(x = PU, y = Value))+
geom_bar(aes(fill = Variable), stat = "identity", position = position_dodge(), alpha = 0.8)+
geom_line(data = df_line, aes(x = PU, y = COM_USD_2, group = 1), size = 2, color = "blue")+
scale_y_continuous(name = "Quantity", limits = c(0,8), sec.axis = sec_axis(~(500/8)*., name = "USD"))+
theme(legend.title = element_blank(),
axis.title.x = element_blank())+
scale_x_discrete(labels = gsub(" ","\n",PU), breaks = PU)