2016-12-06 114 views
0

编辑以反映正在进行的讨论。有条件声明和嵌套Shiny

从我的服务器部分,我想用不同的公式,取决于单选按钮选择这就是所谓的input$beamSupport,进而改变配方,取决于x值。然而,我坚持使用语法。

我也知道我可以通过简单地声明“else ...”来修饰一些代码,但是我想有可能扩展。

现在我得到错误信息“中,如果错误:参数为长度为零”

library(shiny) 

ui <- fluidPage(

    # Style tags for changing the slider 
    tags$style(HTML(".irs-bar {background: none}")), 
    tags$style(HTML(".irs-bar {border-top: none}")), 
    tags$style(HTML(".irs-bar {border-bottom: none}")), 
    tags$style(HTML(".irs-bar-edge {border: none}")), 
    tags$style(HTML(".irs-bar-edge {background: none}")), 


mainPanel(
    titlePanel("Beam Deflection Calculator"), 

    radioButtons("beamSupport", 
       label = ("Beam support type"), 
       choices = list("Simply supported" = 1, 
           "Cantilever" = 2), 
       selected = 1), 

    numericInput("num_W", # Load force, W 
       label = "Enter load force in N.", 
       value = 1), 

    numericInput("num_l", # Length of beam, l 
       label = "Enter beam length in m.", 
       value = 10), 

    numericInput("num_I", # Intertial moment, I (caps i) 
       label = "Enter moment of inertia in m^4.", 
       value = 0.001), 

    numericInput("num_E", 
       label = "Enter Young's modulus in GPa.", 
       value = 200), 

    uiOutput("slider"), # Sliders for a and x 

    textOutput("text_calc") 
) 
) 


server <- function(input, output, session) { 

    output$slider <- renderUI({ 
     tagList(# Need this for multiple reactive sliders 
      sliderInput("slider_a", 
         label = "Choose position, where to apply force, starting from left, in m.", 
         min = 0, 
         max = input$num_l, 
         value = 5, 
         step = 0.1), 

      sliderInput("slider_x", 
         label = "Calculate the deflection, at position starting from left, in m.", 
         min = 0, 
         max = input$num_l, 
         value = 5, 
         step = 0.1) 
     ) 
    }) 

    output$text_calc <- renderText({ 
     W <- input$num_W 
     l <- input$num_l 
     I <- input$num_I 
     E <- input$num_E * 10^9 
     a <- input$slider_a 
     x <- input$slider_x 

     cond <- x < a 

     if (input$beamSupport == 1){ 
      if (cond){ 
       return(paste("The deflection is =", 
         ((W*(l-a)*x)/(6*E*I*l))*(l**2-x**2-(l-a)**2) 
       )) 
      } 
      else{ 
       return(paste("The deflection is =", 
         ((W*a*(l-x))/(6*E*I*l))*(l**2-(l-x)**2-a**2) 
       )) 
      } 
     } 

     if (input$beamSupport == 2){ 
      if (cond){ 
       return(paste("The deflection is =", 
         ((W*x**2)/(6*E*I))*(3*a-x) 
       )) 
      } 
      else{ 
       return(paste("The deflection is =", 
         ((W*a**2)/(6*E*I))*(3*x-a) 
       )) 
      } 
     } 
    }) 
} 

shinyApp(ui = ui, server = server) 

回答

0

试试这个,也请注意,当您使用renderUI将被将获得初始后评估参数会被加载,因此您的slider_aslider_x将为空,直到此时为止。

#rm(list = ls()) 
library(shiny) 

ui <- fluidPage(

    # Style tags for changing the slider 
    tags$style(HTML(".irs-bar {background: none}")), 
    tags$style(HTML(".irs-bar {border-top: none}")), 
    tags$style(HTML(".irs-bar {border-bottom: none}")), 
    tags$style(HTML(".irs-bar-edge {border: none}")), 
    tags$style(HTML(".irs-bar-edge {background: none}")), 


    mainPanel(
    titlePanel("Beam Deflection Calculator"), 

    radioButtons("beamSupport", 
       label = ("Beam support type"), 
       choices = list("Simply supported" = 1, 
           "Cantilever" = 2), 
       selected = 1), 

    numericInput("num_W", # Load force, W 
       label = "Enter load force in N.", 
       value = 1), 

    numericInput("num_l", # Length of beam, l 
       label = "Enter beam length in m.", 
       value = 10), 

    numericInput("num_I", # Intertial moment, I (caps i) 
       label = "Enter moment of inertia in m^4.", 
       value = 0.001), 

    numericInput("num_E", 
       label = "Enter Young's modulus in GPa.", 
       value = 200), 

    uiOutput("slider"), # Sliders for a and x 

    textOutput("text_calc") 
) 
) 


server <- function(input, output, session) { 

    output$slider <- renderUI({ 
    tagList(# Need this for multiple reactive sliders 
     sliderInput("slider_a", 
        label = "Choose position, where to apply force, starting from left, in m.", 
        min = 0, 
        max = input$num_l, 
        value = 5, 
        step = 0.1), 

     sliderInput("slider_x", 
        label = "Calculate the deflection, at position starting from left, in m.", 
        min = 0, 
        max = input$num_l, 
        value = 5, 
        step = 0.1) 
    ) 
    }) 

    output$text_calc <- renderText({ 
    if(is.null(input$slider_a) || is.null(input$slider_x)){ 
     return() 
    } 
    W <- input$num_W 
    l <- input$num_l 
    I <- input$num_I 
    E <- input$num_E * 10^9 
    a <- input$slider_a 
    x <- input$slider_x 

    cond <- x < a 

    if (input$beamSupport == 1){ 
     if (cond){ 
     return(paste("The deflection is =", 
        ((W*(l-a)*x)/(6*E*I*l))*(l**2-x**2-(l-a)**2) 
     )) 
     } 
     else{ 
     return(paste("The deflection is =", 
        ((W*a*(l-x))/(6*E*I*l))*(l**2-(l-x)**2-a**2) 
     )) 
     } 
    } 

    if (input$beamSupport == 2){ 
     if (cond){ 
     return(paste("The deflection is =", 
        ((W*x**2)/(6*E*I))*(3*a-x) 
     )) 
     } 
     else{ 
     return(paste("The deflection is =", 
        ((W*a**2)/(6*E*I))*(3*x-a) 
     )) 
     } 
    } 
    }) 
} 

shinyApp(ui = ui, server = server) 

enter image description here

+0

谢谢!它现在似乎工作。我仍然得到*“警告:错误在if:参数的长度为零”*虽然。这是什么意思? –

+0

如果你运行我的代码,一切工作正常,你必须做一些额外的事情。这意味着你没有照顾'null',比如:'if(input $ SOME_INPUT == null){return()} –

+0

我找不到错误。我已经完成了与你完全相同的事情,除了一些重命名。所有参数都有非零的默认值,所以我需要包含null的位置?全部输出是'堆栈跟踪(最内第一): 79:renderText [〜/桌面/ beamDeflection/beamDeflection.R#85] 78:FUNC 77:origRenderFunc 76:输出$ text_calc 1:runApp' –