【问题标题】:Calling additional functions in Shiny在 Shiny 中调用附加函数
【发布时间】:2016-04-09 00:25:16
【问题描述】:

我开发了一个简单的闪亮应用程序,它以平均 my_mean 和标准差 my_sd 的分布上的分数 my_x 作为输入。作为输出,应用程序返回具有正态标准分布的格点图,对应的 z-scoremy_x。请在GitHub找到该应用的代码。

现在,我想为应用添加第二个功能:

通过检查checkboxInput,我将计算输入的pnorm,并为图形的相对区域着色。

我为图表编写了代码(这里是预期结果的示例),但我不知道如何让它在 Shiny 中工作。特别是,我不知道如何使复选框激活的函数与绘制图形的第一个函数正常工作。

library(lattice)
e4a <- seq(60, 170, length = 10000)
e4b <- dnorm(e4a, 110, 15)
#z-score is calculated with the inputs listed above:

z_score <- (my_x - my_mean)/my_sd

plot_e4d <- xyplot(e4b ~ e4a,
               type = "l",
               main = "Plot 4",
               scales = list(x = list(at = seq(60, 170, 10)), rot = 45),
               panel = function(x,y, ...){
                   panel.xyplot(x,y, ...)
                   panel.abline(v = c(z_score, 110), lty = 2)

                   xx <- c(60, x[x>=60 & x<=z_score], z_score) 
                   yy <- c(0, y[x>=60 & x<=z_score], 0) 
                   panel.polygon(xx,yy, ..., col='red')
               })
print(plot_e4d)

【问题讨论】:

  • 您是否希望在复选框被“选中”时调用您的函数?
  • 每个值在这个向量中代表什么:v = c(80, 95, 110)?我想这些应该是反应值。
  • 是的,这些是用于创建示例图的数字。我将编辑示例图的代码。
  • 你可以给 my_x、my_mean、my_sd 添加值来生成绘图吗?
  • @zx8754 即使回答没有直接解决问题,也给了我启发,所以我找到了解决办法。我会在几分钟内告诉你!

标签: r shiny lattice


【解决方案1】:

我找到了一个有效的解决方案。我很确定它不是最有效的,但它确实有效。它由调用绘图的服务器函数中的if/else 语句组成。我要感谢 @zx8754 的启发。

这是ui.r 文件:

library(shiny)

shinyUI(pageWithSidebar(
headerPanel("Standard Normal"),
sidebarPanel(
    numericInput('mean', 'Your mean', 0),
    numericInput('sd', 'Your standard deviation', 0),
    numericInput('x', 'Your score', 0),
    checkboxInput('p1', label = 'Probability of getting a score smaller than x or z', value = FALSE)
),
mainPanel(
    h3('Standard Normal'),
    plotOutput('sdNorm'),
    h4('Your z-score is:'),
    verbatimTextOutput('z'),
    h4('Your lower tail probability is:'),
    verbatimTextOutput('p1')    
    ))

)

还有server.R 文件:

library(lattice)

shinyServer(
function(input, output){
    output$sdNorm <- renderPlot({
        dt1 <- seq(-3, 3, length = 1000)
        dt2 <- dnorm(dt1, 0, 1)
        my_mean <- input$mean
        my_sd <- input$sd
        my_x <- input$x
        z <- (my_x - my_mean)/my_sd
        if(input$p1){

            xyplot(dt2 ~ dt1,
                   type = "l",
                   main = "Lower tail probability",
                   panel = function(x,y, ...){
                       panel.xyplot(x,y, ...)
                       panel.abline(v = c(z, 0), lty = 2)
                       xx <- c(-3, x[x>=-3 & x<=z], z) 
                       yy <- c(0, y[x>=-3 & x<=z], 0) 
                       panel.polygon(xx,yy, ..., col='red')
                   })

        }else{
            xyplot(dt2 ~ dt1,
                   type = "l",
                   main = "Standard Normal Distribution",
                   panel = function(x, ...){
                       panel.xyplot(x, ...)
                       panel.abline(v = c(z, 0), lty = 2)
                   })
        }

        })
    output$z = renderPrint({
        my_mean <- input$mean
        my_sd <- input$sd
        my_x <- input$x
        z <- (my_x - my_mean)/my_sd
        z
    })
    output$p1 <- renderPrint({
        if(input$p1){
            my_mean <- input$mean
            my_sd <- input$sd
            my_x <- input$x
            p1 <- 1- pnorm(my_x, my_mean, my_sd)
            p1
        } else {
            p1 <- NULL
        }

    })

}

)

【讨论】:

    【解决方案2】:

    这应该可行:

    library(shiny)
    library(lattice)
    
    shinyApp(
      ui = {
        pageWithSidebar(
          headerPanel("Standard Normal"),
          sidebarPanel(
            numericInput('mean', 'Your mean', 80),
            numericInput('sd', 'Your standard deviation', 2),
            numericInput('x', 'Your score', 250),
            checkboxInput("zScoreArea", label = "Area under z-score", value = TRUE)
          ),
          mainPanel(
            h3('Standard Normal'),
            plotOutput('sdNorm'),
            h4('Your z-score is:'),
            verbatimTextOutput('z_score')
          ))
      },
      server = {
        function(input, output){
    
          #data
          dt1 <- seq(60, 170, length = 10000)
          dt2 <- dnorm(dt1, 110, 15)
    
          #xyplot panel= function()
          myfunc <- reactive({
            if(input$zScoreArea){
              function(x,y, ...){
                panel.xyplot(x,y, ...)
                panel.abline( v = c(z_score(), 110), lty = 2)
    
                xx <- c(60, x[x >= 60 & x <= z_score()], z_score())
                yy <- c(0,  y[x >= 60 & x <= z_score()], 0)
                panel.polygon(xx,yy, ..., col='red')
              }
            }else{
              function(x, ...){
                panel.xyplot(x, ...)
                panel.abline(v = c(z_score(), 110), lty = 2)}
    
            }
          })
    
          #reactive z_score for plotting
          z_score <- reactive({
            my_mean <- input$mean
            my_sd <- input$sd
            my_x <- input$x
    
            #return z score
            (my_x - my_mean)/my_sd
          })
    
          output$sdNorm <- renderPlot({
            xyplot(dt2 ~ dt1,
                   type = "l",
                   main = "Plot 4",
                   scales = list(x = list(at = seq(60, 170, 10)), rot = 45),
                   panel = myfunc()
            )
          })
    
          output$z_score = renderPrint({ z_score() })
        }
      }
    )
    

    【讨论】:

    • 对不起@zx8754,我不能让它工作。我很想通过单击复选框为 z 分数(根据输入计算)下的曲线区域着色,但我无法调整您的代码。
    • @Worice 我明白了,试着将你的数据和 z 分数作为一个反应对象保留在 renderPlot 之外。
    猜你喜欢
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 2021-07-02
    • 2013-12-18
    相关资源
    最近更新 更多