r - 使用 R 中的线迹创建堆叠条形图的辅助轴

标签 r dataframe dplyr r-plotly

我正在实现一个函数,该函数构建带有附加线迹线的堆叠%条形图。我可以使用宽格式或长格式数据框创建堆积条形图。下面的两个代码部分生成的图看起来基本相同:

使用宽格式数据框:

library(dplyr)
library(plotly)  # install.packages("plotly")

# simple example data for SO post
some_dates = c(as.Date('2021-01-01'), as.Date('2021-02-01'),
               as.Date('2021-03-01'), as.Date('2021-04-01'))

bar1 = c(0.25,0.45,0.65,0.75)
bar2 = c(0.60,0.40,0.20,0.10)
bar3 = c(0.15,0.15,0.15,0.15)

line_data = c(0,1,2,3)

# wide form dataframe
df_bars = data.frame("db" = some_dates, "b1" = bar1,
                     "b2" = bar2, "b3" = bar3)

df_line = data.frame("line_dates" = some_dates, "line" = line_data)

plot_so1 = plot_ly(x = df_bars$db,
                   y = df_bars[[colnames(df_bars)[2]]],
                   type = 'bar',
                   name = colnames(df_bars)[2]) %>% 
  layout(title = 'My plot title',
         xaxis = list(title = 'db'),
         yaxis = list(title = 'CatProportions'),
         barmode = 'stack',
         showlegend = TRUE)

# Now loop through the rest of the columns except for the ones already used.
# This is done because "in the wild", the plot is being built in a function
# that has data which is passed to it so the number and names of the columns
# that are used to build the plot are not know in advance.
for (col_index in 3:length(some_dates)) {
  plot_so1 =
    add_trace(plot_so1,
              x = df_bars$db,
              y = df_bars[[colnames(df_bars)[col_index]]],
              name = colnames(df_bars)[col_index])
}

使用长格式数据框:

## long form of dataframe #########################
df_bars_long = df_bars %>%
  pivot_longer(!db, names_to = "Categories", values_to = "CatProportions")
# build same plot from long form dataframe
plot_so2 = plot_ly(data = df_bars_long,
                   x = ~db, y = ~CatProportions,
                   color = ~Categories,
                   type = "bar") %>% 
  layout(barmode = "stack")

## above works, now try to add the line trace #####
plot_so2 = plot_ly(data = df_bars_long,
                   x = ~db, y = ~CatProportions,
                   color = ~Categories,
                   type = "bar") %>% 
  # add_trace(x = df_line$line_dates,
  #           y = df_line$line,
  #           type = 'scatter', mode = 'lines', name = 'my line',
  #           line = list(color = '#000000')) %>% 
  layout(title = 'My plot title',
         xaxis = list(title = 'db'),
         yaxis = list(title = 'CatProportions'),
         barmode = 'stack',
         showlegend = TRUE)

enter image description here

我知道使用长格式创建这样的图是最佳实践,但我展示了上面的两种方法,因为我想使用另一个数据帧中的数据添加线条跟踪,该数据帧有一列用于 x 值,一列用于y 值,并且只能使用宽格式添加此跟踪,我可以通过将以下代码段添加到宽格式代码来实现:

plot_so1 = add_trace(plot_so1,
                     x = df_line$line_dates,
                     y = df_line$line,
                     type = 'scatter', mode = 'lines', name = 'my line',
                     line = list(color = '#000000'))

这会产生以下图:

enter image description here

我的主要问题是,如何从数据帧代码的宽范围内为线条轨迹创建辅助 y 轴?我的第二个问题是:我正在寻找的最终图可以用长格式数据框来完成吗?如果可以,怎么做?

这篇文章让我开始解决这个问题:

Stacked Bar Chart with Line Chart not working in R with plotly

但它没有涉及堆叠条形图,这似乎让生活变得更有趣。

最佳答案

这部分不变:

some_dates = c(as.Date('2021-01-01'), as.Date('2021-02-01'),
               as.Date('2021-03-01'), as.Date('2021-04-01'))
line_data = c(0,1,2,3)

# wide form dataframe
df_bars = data.frame("db" = some_dates, "b1" = bar1,
                     "b2" = bar2, "b3" = bar3)

df_line = data.frame("line_dates" = some_dates, "line" = line_data)

如果我们想在图中包含一条线,我们需要知道该线在每个日期的 y 值,因此我们合并 df_linedf_bars_long使用merge() :

df_bars_long = df_bars %>%
  pivot_longer(!db, names_to = "Categories", values_to = "CatProportions") %>%
  merge(df_line, by.y = "line_dates", by.x = "db") %>%
  group_by(db) %>%
  dplyr::mutate(line = ifelse(duplicated(line), NA, line))

> df_bars_long
           db Categories CatProportions line
1  2021-01-01         b1           0.25    0
2  2021-01-01         b2           0.60   NA
3  2021-01-01         b3           0.15   NA
4  2021-02-01         b1           0.45    1
..         ..         ..             ..   ..

然后,情节:

plot_so2 <- plot_ly(data = df_bars_long,
                    x = ~db, y = ~CatProportions,
                    color = ~Categories,
                    type = "bar") %>%
  add_lines(y = ~line,
            name = "my line",
            line = list(color = '#000000'),
            showlegend = TRUE,
            yaxis = "y2") %>%
  layout(title = 'My plot title',
         xaxis = list(title = 'db'),
         yaxis = list(title = 'CatProportions'),
         barmode = 'stack',
         yaxis2 = list(overlaying = "y",
                       side = "right", range = range(na.omit(df_bars_long$line))))
> plot_so2

enter image description here

关于r - 使用 R 中的线迹创建堆叠条形图的辅助轴,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67409961/

相关文章:

python - 仅当第一行是其他下一行的子字符串时,如何对 DataFrame 行与另一行进行平均

scala - 如何将 Scala Spark DataFrames 架构导出到 Json 文件?

r - 使用 dplyr 在数据导入中仅保留一个唯一列

r - 用 dplyr 和条件总结

数据表中的最大行数

r - 按组为 FALSE 和 NA 之间的 TRUE 运行创建计数器

r - 选择具有特定列匹配条件的行

r - mutate 和 case_when 分配了错误的值

python - 我不能按列名提取数据?

r - 按财政季度计算 R 中两个日期之间事件的记录