在 R Shiny 的 Reactive 函数中根据 If 条件分配和使用变量

Assigning and using variables based on If condition in Reactive function of R Shiny

我在 R Shiny 中编写了一些代码行,并且想使用变量 a(表面积)和 v(体积),它们是包含 9 个值的数值向量。这些变量是使用恒定大小向量 d 计算的。 if 条件根据用户从下拉菜单中选择的粒子形状来确定要执行的公式。变量 av 在后续步骤中用于创建数据框、绘图和图表。

我的代码目前面临 2 个问题。

  1. 未计算变量 av 这会导致后续步骤出错,因为我无法创建使用 [=11 的数据帧=] 和 v.

  2. 我在 reactive() 函数中编码的数据帧是可变的,因为值会根据用户的选择而改变,但没有被创建,我不知道为什么.

下面是代码。我是 R 的新手,所以非常感谢任何帮助。

library(shiny)
library(tidyverse)

#UI:
ui <- 
fluidPage(
    navbarPage(
        "TMC Calculator",
        tabPanel(
            "About",
            fluidPage()
        ),
        tabPanel(
            "Contact",
            fluidPage()
        ),
        selectInput("MP_type","Select the type of microplastic",
                    choices=c("High Density Polyethylene" = "HDPE","Polycarbonate" = "PC",
                              "Polyethylene" = "PE","Polyethylene Terephthalate" = "PET",
                              "Polystyrene" = "PS","Polyvinylchloride" = "PVC")),
        selectInput("MP_shape","Select the shape of microplastic",
                    choices=c("Long cylinder","Short cylinder","Sphere",
                              "Oblate spheroid (e=0.2)","Oblate spheroid (e=0.9)")),
        sliderInput("MP_size", "Select the size of microplastic: ",
                    min = 1, 
                    max = 5000, 
                    value = 100, 
                    step = 1),
        textInput("Contaminant", "Enter the contaminant of concern", "Antimony"),
        textInput("AC", "Enter the contaminant adsorption capacity (mg/g)")
        
    ),
    plotOutput("TMC_curve")
)



#SERVER:

#Densities of microplastics
Microplastics_type <- data.frame(Microplastic = c("Polyethylene","Polypropylene","Polystyrene",
                                                  "Polyethylene Terephthalate","Polycarbonate",
                                                  "Polyvinylchloride","High Density Polyethylene"),
                                 Unit_volume = c(1.16, 1.18, 0.93, 0.73, 0.81, 0.72, 1.03))

#Contaminants and their corresponding minimum health endpoint parameters and adsorption capacities
Contaminant <- data.frame("Contaminant"= c("Aluminum","Antimony","Arsenic","BPA","Bromine",
                                           "Cadmium","Chromium","Manganese","Mercury","Propanolol",
                                           "Sulfamethoxazole"),
                          "AC_la" = c(0.375,27.8,1.92,0.19,13,0.00014,0.000454,0.13,
                                      0.00125,0.133,0.087),
                          "G" = c(2.9,0.004,0.003,0.00006,0.01,0.005,0.03,0.12,0.002,0.0005,0.02))

#Defining functions for surface area and volume of shapes (sphere, long & short cylinders and oblate spheroids (e = 0.2 and 0.9))
SPa <- function(d){4*pi*(d/2)^2}
SPv <- function(d){(4/3)*pi*(d/2)^3}
LCa <- function(d){10.5*pi*d^2}
LCv <- function(d){pi*(d/2)^2*(10*d)}
SCa <- function(d){0.6*pi*d^2}
SCv <- function(d){pi*(d/2)^2*(0.1*d)}
OSa <- function(d,e){2*pi*(d/2)^2 + (pi/e)*log((1+e)/(1-e))*((d/2)*(1-e^2)^0.5)^2}
OSv <- function(d,e){(pi/6)*d^3*sqrt(1-e^2)}



function(input, output, session){
    
    d <- c(1, 10, 20, 50, 100, 150, 300, 500, 750)
    
    a <- reactive({
        
        
        if (as.character(input$MP_shape) == "Sphere"){
            SPa(d)
            
        } else if (as.character(input$MP_shape) == "Long Cylinder"){
            LCa(d)
            
        } else if (as.character(input$MP_shape) == "Short Cylinder"){
            SCa(d)
            
        } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.2)"){
            OSa(d, 0.2)
            
        } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.9)"){
            OSa(d, 0.9)
            
        }
    })
    
    v <- reactive ({
        
        
        if (as.character(input$MP_shape) == "Sphere"){
            
            SPv(d)
        } else if (as.character(input$MP_shape) == "Long Cylinder"){
            
            LCv(d)
        } else if (as.character(input$MP_shape) == "Short Cylinder"){
            
            SCv(d)
        } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.2)"){
            
            OSv(d, 0.2)
        } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.9)"){
            
            OSv(d, 0.9)
        }  
        
        Microplastics_type_now <- Microplastics_type %>%
            filter (Microplastic == input$MP_type ) 
        
        TSA <- (1/(Microplastics_type_now$Unit_volume * v) * a)
        
        
        Contaminant_now <- Contaminant %>%
            filter (Contaminant == as.character(input$Contaminant) ) 
        
        TMC <- Contaminant_now$G/(a*((Contaminant_now$AC_la/TSA)))
        
        TMC_curve <- data.frame("TMC" = TMC, "Size" = d)
    })
    
    
    output$TMC_curve <- renderPlot({
        
        ggplot(TMC_curve, aes(x = Size, y = TMC))+
            geom_point()+
            theme_bw()+
            scale_y_log10()
        
    })
    
}

有几点需要考虑:

  1. av 是反应值,必须像函数一样调用它们,例如 a().
  2. v 在响应式定义 v 中被调用,因为在任何环境中都没有使用该名称声明的对象会导致错误,或者如果它存在则不会具有所需的值。
  3. 第二个 selectInput 中定义的选择向量与 if 语句中的选择向量不匹配。 (注意区分大小写)

代码:

library(shiny)
library(tidyverse)

Microplastics_type <- data.frame(Microplastic = c("Polyethylene","Polypropylene","Polystyrene",
                                                  "Polyethylene Terephthalate","Polycarbonate",
                                                  "Polyvinylchloride","High Density Polyethylene"),
                                 Unit_volume = c(1.16, 1.18, 0.93, 0.73, 0.81, 0.72, 1.03))

#Contaminants and their corresponding minimum health endpoint parameters and adsorption capacities
Contaminant <- data.frame("Contaminant"= c("Aluminum","Antimony","Arsenic","BPA","Bromine",
                                           "Cadmium","Chromium","Manganese","Mercury","Propanolol",
                                           "Sulfamethoxazole"),
                          "AC_la" = c(0.375,27.8,1.92,0.19,13,0.00014,0.000454,0.13,
                                      0.00125,0.133,0.087),
                          "G" = c(2.9,0.004,0.003,0.00006,0.01,0.005,0.03,0.12,0.002,0.0005,0.02))

#Defining functions for surface area and volume of shapes (sphere, long & short cylinders and oblate spheroids (e = 0.2 and 0.9))
SPa <- function(d){4*pi*(d/2)^2}
SPv <- function(d){(4/3)*pi*(d/2)^3}
LCa <- function(d){10.5*pi*d^2}
LCv <- function(d){pi*(d/2)^2*(10*d)}
SCa <- function(d){0.6*pi*d^2}
SCv <- function(d){pi*(d/2)^2*(0.1*d)}
OSa <- function(d,e){2*pi*(d/2)^2 + (pi/e)*log((1+e)/(1-e))*((d/2)*(1-e^2)^0.5)^2}
OSv <- function(d,e){(pi/6)*d^3*sqrt(1-e^2)}


ui <- fluidPage(
    navbarPage(
        "TMC Calculator",
        tabPanel(
            "About",
            fluidPage(
                
                
            )
        ),
        tabPanel(
            "Contact",
            fluidPage(
                
            )
            
        ),
        
        
        
        selectInput("MP_type","Select the type of microplastic",
                    choices = unique(Microplastics_type$Microplastic)),
        
        selectInput("MP_shape","Select the shape of microplastic",
                    choices=c("Long Cylinder","Short Cylinder","Sphere",
                              "Oblate Spheroid (e=0.2)","Oblate Spheroid (e=0.9)")),
        
        sliderInput("MP_size", "Select the size of microplastic: ",
                    min = 1, 
                    max = 5000, 
                    value = 100, 
                    step = 1),
        
        selectInput("Contaminant", "Enter the contaminant of concern",choices = unique(Contaminant$Contaminant), "Antimony"),
        
        textInput("AC", "Enter the contaminant adsorption capacity (mg/g)")
        
        
        
        
        
    ),
    plotOutput("TMC_curve")
) 


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

    
    
    
    
        
        d <- c(1, 10, 20, 50, 100, 150, 300, 500, 750)
        
        a <- reactive({
            
            
            if (as.character(input$MP_shape) == "Sphere"){
                SPa(d)
                
            } else if (as.character(input$MP_shape) == "Long Cylinder"){
                LCa(d)
                
            } else if (as.character(input$MP_shape) == "Short Cylinder"){
                SCa(d)
                
            } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.2)"){
                OSa(d, 0.2)
                
            } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.9)"){
                OSa(d, 0.9)
                
            }
        })
        
        v <- reactive ({
            
            
            if (as.character(input$MP_shape) == "Sphere"){
                
                SPv(d)
            } else if (as.character(input$MP_shape) == "Long Cylinder"){
                
                LCv(d)
            } else if (as.character(input$MP_shape) == "Short Cylinder"){
                
                SCv(d)
            } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.2)"){
                
                OSv(d, 0.2)
            } else if (as.character(input$MP_shape) == "Oblate Spheroid (e=0.9)"){
                
                OSv(d, 0.9)
            } })  
            
        TMC_curve_df <- reactive({
            print(a())
            print(v())
            
            
            Microplastics_type_now <- Microplastics_type %>%
                filter (Microplastic == input$MP_type ) 
            
            TSA <- (1/(Microplastics_type_now$Unit_volume * v()) * a())
            
            
            Contaminant_now <- Contaminant %>%
                filter (Contaminant == as.character(input$Contaminant) ) 
            
            TMC <- Contaminant_now$G/(a()*((Contaminant_now$AC_la/TSA)))
            
            print(TMC)
            
            TMC_curve <- data.frame("TMC" = TMC, "Size" = d)
        })
        
        
        output$TMC_curve <- renderPlot({
            
            ggplot(TMC_curve_df(), aes(x = Size, y = TMC))+
                geom_point()+
                theme_bw()+
                scale_y_log10()
            
        })
        
    }


shinyApp(ui, server)