具有其他刻度的第二个 y 轴

second y-axis with other scale

我使用 ggplot2 geom_bar 创建了一个条形图,并希望在条形中有两个指标。我用 melt 这样做。但是,我现在需要另一个刻度的第二个 y 轴,因为两个指标的数字相差太大。

在下面的数据框和我使用的代码中:

df <- data.frame(categories = c("politics", "local", "economy", "cultural events", 
                                "politics", "local", "economy", "cultural events"), 
               metric = c("page", "page", "page", "page", 
                          "product", "product", "product", "product"), 
               value = c(100L, 50L, 20L, 19L, 
                         950000L, 470000L, 50000L, 1320L))

在下面我用来创建绘图和第二个 y 轴的代码中:

x <- ggplot(df, aes(x=categories, y=value, fill = metric))
x + geom_bar(stat = "identity", position = "dodge") +
  scale_y_continuous(sec.axis=sec_axis(~. *1000), limits=c(1,1000))

但是,现在图表中不再出现柱状图了...有人知道如何解决这个问题吗?

您可以将它们堆叠在一起(或将它们分面),而不是在同一图上显示不同的条形图:

正如@ConorNeilson 已经在评论中提到的,您不必(也不应该)用 df$ 指定变量。 ggplot 知道在指定的 data.frame df.
中寻找它们 facet_grid 调用中的 free_y 参数可以在 y 轴上显示不同的比例。

library(ggplot2)
ggplot(df, aes(x = categories, y = value, fill = metric)) + 
  geom_bar(stat = "identity", position = "dodge") +
  facet_grid(metric~., scales = "free_y")

您可以在 log10 范围内比较不同的值:

ggplot(df, aes(x = categories, y = value, fill = metric)) + 
  geom_bar(stat = "identity", position = "dodge") +
  scale_y_log10(name = "value (log10 scale)", 
                breaks = 10^(0:10), labels = paste0(10, "^", 0:10))

另一种方法是使用 highcharter

library(dplyr)
library(tidyr)
library(highcharter)

#convert your data in wide format
df <- df %>% spread(metric, value)

#plot
highchart() %>% 
  hc_xAxis(categories = df$categories) %>%
  hc_yAxis_multiples(
    list(lineWidth = 3, title = list(text = "Page")),
    list(opposite = TRUE, title = list(text = "Product"))
  ) %>% 
  hc_add_series(type = "column", data = df$page) %>% 
  hc_add_series(type = "line", data = df$product, yAxis=1) # replace "line" with "column" to have it in bar format

输出图为:

示例数据:

df <- structure(list(categories = structure(c(4L, 3L, 2L, 1L, 4L, 3L, 
2L, 1L), .Label = c("cultural events", "economy", "local", "politics"
), class = "factor"), metric = structure(c(1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L), .Label = c("page", "product"), class = "factor"), 
    value = c(100L, 50L, 20L, 19L, 950000L, 470000L, 50000L, 
    1320L)), .Names = c("categories", "metric", "value"), row.names = c(NA, 
-8L), class = "data.frame")