【问题标题】:Rendering ggvis controls in shiny以闪亮的方式渲染 ggvis 控件
【发布时间】:2014-09-25 03:07:53
【问题描述】:

我无法让输入滑块在闪亮的应用程序中呈现在 ggvis 图中。在没有输入滑块的情况下,绘图渲染得很好,但是在添加它之后闪亮会抛出这个错误:

Listening on http://xxxxxxxxxxxxxx
Error in eval(expr, envir, enclos) : could not find function "compdat" 

服务器.R:


    library(shiny)
    library(ggvis)

    data<-data.frame(var1=rnorm(30,5,2.3),var2=rbeta(30,1.5,.8),var3=rnorm(30,10,2.5))

    shinyServer(function(input, output,session) {

    compdat<-reactive({data[, c(input$xInp,input$yInp)]}) 

    vis1 <-reactive({  

      compdat %>% ggvis(x= ~compdat()[,1],y= ~compdat()[,2]) %>% 
       layer_points(fill:="red") %>% layer_smooths(span=input_slider(.1,1,id="scores_ui"))   

    })

    vis1 %>% bind_shiny("scores",controls_id="scores_ui")

    vis2<-reactive({ 

      compdat %>% ggvis(x= ~compdat()[,1],y= ~compdat()[,2]) %>% 
       layer_points(fill:="red") %>% ayer_smooths(span=input_slider(.1,1,id="loadings_ui"))

    })

    vis2 %>% bind_shiny("loadings",controls_id="loadings_ui")

    })

ui.R:



    shinyUI(fluidPage(

     title="PCA Explorer", 
     h2("Principal Component Explorer"),

     fluidRow(
      column(6,ggvisOutput("scores"),
               uiOutput("scores_ui")),
      column(6,ggvisOutput("loadings"),
               uiOutput("loadings_ui"))
     ),

     br(),

     fluidRow(
      column(6,h3("Component Selection"),selectInput('xInp',"X Variable",names(data)),
       selectInput('yInp',"Y Variable",names(data),selected=names(data)[[2]])),
      column(6,h3("Summary of Selected Data Points"),verbatimTextOutput("diagn"))

      )
    ))

任何关于如何让滑块呈现的见解都会很棒。我花了相当多的时间来挖掘这个问题。在此先感谢

【问题讨论】:

    标签: r shiny ggvis


    【解决方案1】:

    可以在Movie Explorer example 中找到一个很好的示例,演示如何使用 selectizeInput 自定义 X/Y 轴变量。

    但是,在响应式环境中包装 ggvis() 函数存在明显的缺点(或错误),即一旦更改 input$xInp$ 或 input$yInp,layer_smooths() 就会停止对滑块输入做出反应。

    您的代码的另一个潜在问题是data 对ui.R 不可见。 您可能想要创建一个包含您的 data 对象的 global.R 文件。

    下面我将介绍两种方法,说明如何通过选择 X/Y 变量与 ggvis 图进行交互。你可以在server.R找到它们。

    global.R

    data <- data.frame(var1=rnorm(30,5,2.3),
                     var2=rbeta(30,1.5,.8),
                     var3=rnorm(30,10,2.5))
    

    ui.R

    library(shiny)
    
    shinyUI(fluidPage(
    
        title="PCA Explorer", 
        h2("Principal Component Explorer"),
    
        fluidRow(
            column(6,
                ggvisOutput("scores"),
                uiOutput("scores_ui")),
            column(6,
                ggvisOutput("loadings"),
                uiOutput("loadings_ui"))
        ),
    
        br(),
    
        fluidRow(
            column(6,
                h3("Component Selection"),
                selectInput('xInp',"X Variable", choices=names(data),
                            selected=names(data)[[1]]),
                selectInput('yInp',"Y Variable", choices=names(data), 
                            selected=names(data)[[2]])
            ),
            column(6,
                h3("Summary of Selected Data Points"),
                verbatimTextOutput("diagn"))
        )
    ))
    

    服务器.R

    library(shiny)
    library(ggvis)
    
    shinyServer(function(input, output,session) {
        # Approach 1: regenerate a compdat object once the input changes
        # rename the X/Y variables to fixed names.
        compdat <- reactive({
            x <- data[, c(input$xInp, input$yInp)]
            names(x) <- c("x", "y")
            x
        })
    
        # NOTE that you use compdat here instead of compdat()
        compdat %>% ggvis(x=~x, y=~y) %>%
            layer_points(fill:="red") %>%
            layer_smooths(span=input_slider(.1,1)) %>% 
            bind_shiny("scores", controls_id="scores_ui")
    
        # Approach 2: wrap ggvis in a reactive environment
        # This however, would stop to react to slider input 
        # once input$xInp or input$yInp changes.
        vis2 <- reactive({ 
            xvar <- prop("x", as.symbol(input$xInp))
            yvar <- prop("y", as.symbol(input$yInp))
    
            data %>% ggvis(x=xvar, y=yvar) %>% 
            layer_points(fill:="red") %>% 
            layer_smooths(span=input_slider(.1,1))
        })
    
        vis2 %>% bind_shiny("loadings", controls_id="loadings_ui")
    })
    

    这两种方法都应该有效(嗯,几乎)。但是等等,一旦您更改 X/Y 变量,您可能会看到平滑层停止响应您的滑块更改。

    要解决此问题,请考虑以下解决方案。


    解决方法 2 的问题

    我之前提到的错误可以通过在ui.R 中创建一个sliderInput 来修复。

    ui.R

    library(shiny)
    
    shinyUI(fluidPage(
    
        title="PCA Explorer", 
        h2("Principal Component Explorer"),
    
        fluidRow(
            column(6,
                ggvisOutput("scores"),
                uiOutput("scores_ui")
            ),
            column(6,
                ggvisOutput("loadings"),
                uiOutput("loadings_ui"),
                # Create a slider by Shiny, instead of by ggvis.
                sliderInput('smooth_span', 
                            h5("Smoothing span for plot 2"), 
                            .1, 1, value=0.5)
            )
        ),
    
        br(),
    
        fluidRow(
            column(6,
                h3("Component Selection"),
                selectInput('xInp',"X Variable", choices=names(data),
                            selected=names(data)[[1]]),
                selectInput('yInp',"Y Variable", choices=names(data), 
                            selected=names(data)[[2]])
            ),
            column(6,
                h3("Summary of Selected Data Points"),
                verbatimTextOutput("diagn"))
        )
    ))
    

    服务器.R

    library(shiny)
    library(ggvis)
    
    shinyServer(function(input, output,session) {
        # Approach 1: regenerate a compdat object once the input changes
        # rename the X/Y variables to fixed names.
        compdat <- reactive({
            x <- data[, c(input$xInp, input$yInp)]
            names(x) <- c("x", "y")
            x
        })
    
        # NOTE that you use compdat here instead of compdat()
        compdat %>% ggvis(x=~x, y=~y) %>%
            layer_points(fill:="red") %>%
            layer_smooths(span=input_slider(.1,1)) %>% 
            bind_shiny("scores", controls_id="scores_ui")
    
        # Approach 2: wrap ggvis in a reactive environment
        # This however, would stop to react to slider input 
        # once input$xInp or input$yInp changes.
        vis2 <- reactive({ 
            xvar <- prop("x", as.symbol(input$xInp))
            yvar <- prop("y", as.symbol(input$yInp))
            smooth.span <- input$smooth_span
    
            data %>% ggvis(x=xvar, y=yvar) %>% 
            layer_points(fill:="red") %>% 
            # FIXED: use the value from the input object, instead of a input_slider
            layer_smooths(span=smooth.span)
        })
    
        vis2 %>% bind_shiny("loadings", controls_id="loadings_ui")
    })
    

    最后的话

    将ggvis 包装到响应式环境中存在一些缺点:

    • 性能降低:因为一旦因输入变量发生变化,就需要重新绘制整个图表。
    • 缺少过渡动画:由于重新绘制了整个图形,您看不到在方法 1 中看到的漂亮过渡效果。

    不过,它确实有几个优点:

    • 更高的灵活性:在响应式环境中包装 ggvis 是,AFAIK,如果您想动态更改 X-Y 轴标签(例如,取决于您的 input$xInp),目前是 唯一 方式。因为ggvis 只计算并将数据绑定到ggvis 对象一次,所以对轴标签所做的更改不会实时反映。但是,由于在响应式环境中包装 ggvis 会导致整个图形重绘,因此标签也会在重绘中更新。

    【讨论】:

    • 感谢您查看此内容。我同时实现了这两种方法,并认为我当时更喜欢方法 1。 TC。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 2015-01-11
    • 2016-06-12
    • 2016-03-04
    • 2015-06-23
    相关资源
    最近更新 更多