基于缩放交互的子集数据框

时间:2015-11-17 03:29:28

标签: r ggplot2 shiny

我正在R中构建一个交互式闪亮应用,并希望显示两个散点图:

  1. 整个数据集(左)
  2. Zoomed Region(右)
  3. 左图不应更改,用于为右图选择不同的区域。它类似于示例代码(http://shiny.rstudio.com/gallery/plot-interaction-zoom.html)中的 plot2 plot3

    我想显示两个图的统计数据和线性回归,并根据右图中选择的区域更新缩放图的信息。我想到这样做的一种方法是使用画笔对原始数据(df_mtcars)进行子集化并将其保存为新的数据帧(df_mtcars2)。

    我对R仍然有点新,并且无法找到关于此的很多信息。我发现了一种用ggvis(here)做类似事情的方法,但有没有办法用ggplot2做呢?如果有更简单的方法,我也会接受其他建议。

    这是我的代码:

    app.R

    library(ggplot2)
    library(dplyr)
    
    df_mtcars <- mtcars %>%
      select(wt,mpg)
    
    df_mtcars2 <- df_mtcars
    #choose selection based on brushed/zoomed data
    
    ui <- fluidPage(
      fluidRow(
        column(width = 12, class = "well",
           h4("Left plot controls right plot"),
           fluidRow(
             column(width = 6,
                    h5("Entire Dataset (left)"),
                    plotOutput("plot1", height = 350,
                               brush = brushOpts(
                                 id = "plot1_brush",
                                 resetOnNew = TRUE
                               )
                    )
             ),
             column(width = 6,
                    h5("Zoomed Region (right)"),
                    plotOutput("plot2", height = 350)
             )
           ),
           fluidRow(
             column(width = 6,
                    verbatimTextOutput("summary1")),
             column(width = 6, 
                    verbatimTextOutput("summary2"))
           )    
        )
      )
    )
    server <- function(input, output) {
    
    # Linked plots (left and right)
    ranges <- reactiveValues(x = NULL, y = NULL)
    
    output$plot1 <- renderPlot({
      ggplot(df_mtcars, aes(wt, mpg)) + geom_point() + 
      geom_smooth(method = "lm", color = "red")
    })
    
    output$plot2 <- renderPlot({
      #dataset should be changed to df_mtcars2
      ggplot(df_mtcars2, aes(wt, mpg)) + geom_point() + 
        geom_smooth(method = "lm", color = "blue") +
        # if using df_mtcars2, should get rid of coord_cartesian range (?)
        coord_cartesian(xlim = ranges$x, ylim = ranges$y) 
    })
    
    # When a double-click happens, check if there's a brush on the plot.
    # If so, zoom to the brush bounds; if not, reset the zoom.
    observe({
      brush <- input$plot1_brush
      if (!is.null(brush)) {
        ranges$x <- c(brush$xmin, brush$xmax)
        ranges$y <- c(brush$ymin, brush$ymax)
      } else {
        ranges$x <- NULL
        ranges$y <- NULL
      }
    })
    
    output$summary1 <- renderPrint({
      summary(df_mtcars)
      #how to add linear equation and R^2 (?)
    })
    
    output$summary2 <- renderPrint({
      summary(df_mtcars2) #should be df_mtcars2
      #how to add linear equation and R^2 (?)
     })
    }
    

1 个答案:

答案 0 :(得分:1)

要获取刷新数据,您可以使用brushedPoint函数,它输出刷子点的行号。然后,您可以直接转到ggplotplot2中的summary2。这是一个例子:

server <- function(input, output) {

  values <- reactiveValues(data=df_mtcars)

  output$plot1 <- renderPlot({
    ggplot(df_mtcars, aes(wt, mpg)) + geom_point() + 
      geom_smooth(method = "lm", color = "red")
  })

  output$plot2 <- renderPlot({
    ggplot(values$data, aes(wt, mpg)) + geom_point() + 
      geom_smooth(method = "lm", color = "blue") 
  })

  observe({
    if (!is.null(input$plot1_brush)) {      
      values$data <- brushedPoints(df_mtcars, input$plot1_brush)
    } else {     
      values$data <- df_mtcars
    }
  })

  output$summary1 <- renderPrint({
    summary(df_mtcars)
  })

  output$summary2 <- renderPrint({
    summary(values$data)
  })
}

要显示线性方程式,您可以在verbatimTextOutput("summary2_lm")中添加ui.R,在server.R输出中添加线性方程式和R2系数:

output$summary2_lm <- renderPrint({
    m <- lm(mpg ~ wt, values$data);
    paste("y=",format(coef(m)[1], digits = 2),"x+",format(coef(m)[2], digits = 2)," R2=",format(summary(m)$r.squared, digits = 3))
  })

将等式和R2作为字符串的函数的灵感来自docs on BodyParser