Как объединить серию линий на двух графиках, отображаемых на автографике, в один график, используя одну и ту же ось Y и две разные оси X?

В приведенном ниже коде я отображаю два отдельных графика, используяфункция. Первый сюжет () позволяет пользователю преобразовать ряд данных с помощью ползунка, тогда как 2-й график показывает исходный непреобразованный ряд () и полностью статично. Я хотел бы показать две серии данных на одном графике, причем первая серия показана на основной оси x (слева, а ее значения оси x варьируются в зависимости от ввода ползунка), а вторая серия показана на вторичная ось x (справа, и она всегда остается фиксированной, так как показывает исходные данные до преобразования). Я хотел бы разместить две серии на одном графике, чтобы пользователь мог видеть влияние преобразования на форму данных. Это то, что было легко сделать в XLS, но я перешел на R.

Любые рекомендации, как это сделать?

Код:

      library(feasts)
library(fabletools)
library(ggplot2)
library(shiny)
library(tsibble)

DF <- data.frame(
  Month = c(1:12),
  StateX = c(59,77,45,42,32,26,27,21,19,22,24,10)
)
DF1 <- DF %>% as_tsibble(index = Month)

library(shiny)
ui <- fluidPage(
  sliderInput("lambda","Transformation lambda:",min=-2,max=2,value=0.5,step = 0.1),
  plotOutput("transPlot1"),
  plotOutput("transPlot2"),
)
server <- function(input, output) {
  
  output$transPlot1 <- renderPlot({
    DF1 %>%
      autoplot(box_cox(StateX, input$lambda)) +
      labs(y = "",
           title = latex2exp::TeX(paste0(
             "Transformed units reaching StateX",
             round(input$lambda,2))))
  })
  
  output$transPlot2 <- renderPlot({
    autoplot(DF1, StateX) +
      labs(y = "")
  })  
}
shinyApp(ui, server)

1 ответ

Одним из вариантов достижения желаемого результата было бы добавление вашей непреобразованной серии вautoplotчерезgeom_lineи добавить вторичную шкалу. Как обычно при добавлении вторичной гаммы кggplotэто требует некоторого преобразования данных для отображения на вторичной оси. С этой целью я добавил реактив для выполнения всех преобразований, включая преобразование Бокса-Кокса и преобразование, необходимое для вторичной шкалы. Для последней части я используюscales::rescale.

      library(feasts)
#> Loading required package: fabletools
library(fabletools)
library(ggplot2)
library(shiny)
library(tsibble)
library(dplyr)
library(scales)

DF <- data.frame(
  Month = c(1:12),
  StateX = c(59, 77, 45, 42, 32, 26, 27, 21, 19, 22, 24, 10)
)
DF1 <- DF %>% as_tsibble(index = Month)

library(shiny)
ui <- fluidPage(
  sliderInput("lambda", "Transformation lambda:", min = -2, max = 2, value = 0.5, step = 0.1),
  plotOutput("transPlot1")
)
server <- function(input, output) {
  DF1_trans <- reactive({
    DF1 %>%
      mutate(
        state_x_box = box_cox(StateX, input$lambda),
        state_x_raw = scales::rescale(StateX, to = range(state_x_box))
      )
  })
  
  output$transPlot1 <- renderPlot({
    to_range <- range(DF1_trans()$StateX)

    DF1_trans() %>%
      autoplot(state_x_box) +
      geom_line(data = DF1_trans(), aes(Month, state_x_raw, color = "Untransformed Series")) +
      scale_y_continuous(
        sec.axis = sec_axis(
          name = "Untransformed",
          trans = ~ scales::rescale(.x, to = to_range))) +
      labs(
        y = "",
        title = latex2exp::TeX(paste0(
          "Transformed units reaching StateX",
          round(input$lambda, 2)
        ))
      )
  })
}
shinyApp(ui, server)
#> 
#> Listening on http://127.0.0.1:3492

Другие вопросы по тегам