R/mod_train_test.R

Defines functions mod_train_test_server mod_train_test_ui

#' Train-Test UI Function
#'
#' @description A shiny Module.
#'
#' @param id,input,output,session Internal parameters for {shiny}.
#'
#' @noRd 
#'
#' @importFrom shiny NS tagList 
mod_train_test_ui <- function(id, nombrePred) {
  ns <- NS(id)
  
  opcVC <- tags$div(
    id = ns("titleVC"),
    fluidRow(
      col_7(tags$b("Experimento: ")),
      col_5(selectInput(ns("vci"), NULL, c(1), selected = 1, width = "100%"))
    )
  )
  
  tagList(
    tabBoxPrmdt(
      id = ns("BoxModel"), opciones = NULL, title = opcVC,
      
      tabPanel(
        title = labelInput("generatem"), value = "tabModelo",
        tags$div(
          style = "height: 70vh;",
          col_5(
            wellPanel(
              style = "background-color: #666;color: white;",
              options.run(ns("runModelo")), tags$hr(style = "margin-top: 0px;"),
              generar.opciones(nombrePred, ns)
            )
          ),
          col_7(
            withLoader(verbatimTextOutput(ns("txtmodel")), 
                       type = "html", loader = "loader4"))
        )
      ),
      
      tabPanel(
        title = labelInput("indices"), value = "tabIndices",
        tags$div(
          col_6(
            tags$div(style = "margin-top: 77px;"),
            valueBoxOutput(ns("RMSEBox"), width = 6),
            valueBoxOutput(ns("MAEBox"), width = 6),
            valueBoxOutput(ns("REBox"), width = 6),
            valueBoxOutput(ns("CORBox"), width = 6)
          ),
          col_6(
            withLoader(DT::dataTableOutput(ns("modeloPredTable")), 
                       type = "html", loader = "loader4")
          )
        ),
        tags$hr(style = "margin-top: 70vh;"),
        tags$div(
          column(
            width = 12, align = "center", 
            tags$h3(labelInput("resumenVarPre"))
          )
        ),
        tags$div(
          style = "text-align: -webkit-center;",
          withLoader(tableOutput(ns('VARP')), type = "html", loader = "loader4")
        )
      ),
      
      if(nombrePred == "reg") {
        tabPanel(title = labelInput("coeff"), value = "tabRlCoef",
                 withLoader(DT::dataTableOutput(ns("rlCoefTable")), 
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "tree") {
        tabPanel(title = labelInput("garbol"), value = "tabPlotTree",
                 withLoader(plotOutput(ns('plot_tree'), height = "70vh"), 
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "rndf") {
        tabPanel(title = labelInput("evolerror"), value = "tabErrorForest",
                 withLoader(echarts4rOutput(ns('plot_error_rndf'), height = "70vh"),
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "rndf") {
        tabPanel(title = labelInput("varImp"), value = "tabVarForest",
                 withLoader(echarts4rOutput(ns('plot_var_rndf'), height = "70vh"),
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "boost") {
        tabPanel(title = labelInput("evolerror"), value = "tabErrorBoost",
                 withLoader(echarts4rOutput(ns('plot_error_boost'), height = "70vh"),
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "boost") {
        tabPanel(title = labelInput("varImp"), value = "tabVarBoost",
                 withLoader(echarts4rOutput(ns('plot_var_boost'), height = "70vh"),
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "xgb") {
        tabPanel(title = labelInput("varImp"), value = "tabVarXGB",
                 withLoader(echarts4rOutput(ns('plot_var_xgb'), height = "70vh"),
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "nnet") {
        tabPanel(title = labelInput("redPlot"), value = "tabPlotRedes",
                 withLoader(plotOutput(ns('plot_nnet'), height = "70vh"), 
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "regp") {
        tabPanel(title = labelInput("posibLanda"), value = "tabLambda",
                 withLoader(echarts4rOutput(ns('plot_regp_lambda'), height = "70vh"), 
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "regp") {
        tabPanel(
          title = labelInput("gcoeff"),value = "tabCoeff",
          tags$div(
            style = "height: 70vh;",
            col_5(
              wellPanel(
                style = "background-color: #666;color: white;",
                fluidRow(
                  col_8(
                    numericInput(ns("lambda"), labelInput("lambda"),
                                 value = 0, width = "100%")
                  ),
                  col_4(
                    tags$div(style = "margin-top: 24px;"),
                    actionButton(ns("calcularLambda"), "Calcular lambda",
                                 width = "100%")
                  )
                ),
                tags$hr(),
                fluidRow(
                  col_12(actionButton(ns("aplicarLambda"), tr("aplicar"),
                                      width = "100%"))
                )
              ),
              withLoader(verbatimTextOutput(ns('txtBetas')), 
                         type = "html", loader = "loader4")
            ),
            col_7(
              withLoader(echarts4rOutput(ns('plot_regp_coeff'), height = "70vh"), 
                         type = "html", loader = "loader4"))
          )
        )
      },
      
      if(nombrePred == "rdim") {
        tabPanel(title = labelInput("RMSE"), value = "tabRMSEPlot",
                 withLoader(echarts4rOutput(ns('plot_rmse'), height = "70vh"),
                            type = "html", loader = "loader4"))
      },
      
      if(nombrePred == "rdim") {
        tabPanel(title = labelInput("VarExp"), value = "tabVAREPlot",
                 withLoader(echarts4rOutput(ns('plot_vare'), height = "70vh"),
                            type = "html", loader = "loader4"))
      },
      
      tabPanel(
        title = labelInput("varError"), value = "tabVariacion",
        wellPanel(
          style = "background-color: #666;color: white;",
          fluidRow(
            col_12(selectInput(ns("sel_ind_err"), labelInput("selindice"), 
                               choices = c("RMSE", "MAE", "RE", "COR"))),
          ),
          hr(),
          fluidRow(
            col_12(actionButton(ns("aplicar2"), labelInput("aplicar"), NULL, "100%"))
          )
        ),
        withLoader(echarts4rOutput(ns("VARE"), height = "65vh", width = "100%"), 
                   type = "html", loader = "loader4")
      )
    )
  )
}

#' Train-Test Server Function
#'
#' @noRd 
mod_train_test_server <- function(input, output, session, updateData, modelos, nombrePred, codedioma){
  ns <- session$ns
  modelosrv <- rv(modelos = NULL, modelo = NULL, i = 1)
  
  # Actualiza la cantidad de capas ocultas
  observeEvent(c(input$n_hidden, updateData$variable.predecir), {
    if(!is.null(updateData$variable.predecir) && !is.null(input$n_hidden)) {
      for (i in 1:10) {
        if(i <= input$n_hidden) {
          shinyjs::show(paste0("hidden", i))
        } else {
          shinyjs::hide(paste0("hidden", i))
        }
      }
    }
  })
  
  # Habilita la cantidad de componentes
  observeEvent(input$ncompdef, {
    if (as.logical(input$ncompdef)) {
      shinyjs::enable("ncomp")
    } else {
      shinyjs::disable("ncomp")
    }
  })
  
  observe({
    datos    <- isolate(updateData$datos)
    variable <- isolate(updateData$variable.predecir)
    choices  <- as.character(unique(datos[, variable]))
    
    if(!is.null(modelos[[nombrePred]])) {
      showTab(inputId = "BoxModel", target = "tabIndices")
      showTab(inputId = "BoxModel", target = "tabEvolucion")
      showTab(inputId = "BoxModel", target = "tabRlCoef")
      showTab(inputId = "BoxModel", target = "tabSvmPlot")
      showTab(inputId = "BoxModel", target = "tabPlotTree")
      showTab(inputId = "BoxModel", target = "tabErrorForest")
      showTab(inputId = "BoxModel", target = "tabVarForest")
      showTab(inputId = "BoxModel", target = "tabErrorBoost")
      showTab(inputId = "BoxModel", target = "tabVarBoost")
      showTab(inputId = "BoxModel", target = "tabVarXGB")
      showTab(inputId = "BoxModel", target = "tabPlotRedes")
      showTab(inputId = "BoxModel", target = "tabLambda")
      showTab(inputId = "BoxModel", target = "tabCoeff")
      showTab(inputId = "BoxModel", target = "tabRMSEPlot")
      showTab(inputId = "BoxModel", target = "tabVAREPlot")
      showTab(inputId = "BoxModel", target = "tabVariacion")
    } else {
      updateTabsetPanel(session, "BoxModel", "tabModelo")
      hideTab(inputId = "BoxModel", target = "tabIndices")
      hideTab(inputId = "BoxModel", target = "tabEvolucion")
      hideTab(inputId = "BoxModel", target = "tabRlCoef")
      hideTab(inputId = "BoxModel", target = "tabCortes")
      hideTab(inputId = "BoxModel", target = "tabSvmPlot")
      hideTab(inputId = "BoxModel", target = "tabPlotTree")
      hideTab(inputId = "BoxModel", target = "tabErrorForest")
      hideTab(inputId = "BoxModel", target = "tabVarForest")
      hideTab(inputId = "BoxModel", target = "tabErrorBoost")
      hideTab(inputId = "BoxModel", target = "tabVarBoost")
      hideTab(inputId = "BoxModel", target = "tabVarXGB")
      hideTab(inputId = "BoxModel", target = "tabPlotRedes")
      hideTab(inputId = "BoxModel", target = "tabLambda")
      hideTab(inputId = "BoxModel", target = "tabCoeff")
      hideTab(inputId = "BoxModel", target = "tabRMSEPlot")
      hideTab(inputId = "BoxModel", target = "tabVAREPlot")
      hideTab(inputId = "BoxModel", target = "tabVariacion")
    }
    
    if(!is.null(input$BoxModel)) {
      if(input$BoxModel == "tabVariacion") {
        hide("titleVC")
      } else {
        show("titleVC")
      }
    }
  })
  
  observeEvent(c(updateData$datos, updateData$variable.predecir), {
    modelosrv$modelos <- NULL
    modelosrv$modelo  <- NULL
    modelosrv$i       <- 1
    datos    <- updateData$datos
    variable <- updateData$variable.predecir
    choices  <- as.character(unique(datos[, variable]))
    predictoras <- colnames.empty(var.numericas(updateData$datos))
    
    updateNumericInput(session, "kmax", value = round(sqrt(ncol(datos))))
    updateNumericInput(session, "mtry", value = round(sqrt(ncol(datos))))
    updateNumericInput(session, "ncomp", value = round((ncol(datos))))
    
    updateSelectizeInput(session, "var_svm_plot", choices = predictoras)
    
    updateTabsetPanel(session, "BoxModel", selected = "tabModelo")
  })
  
  observeEvent(c(updateData$datos, updateData$variable.predecir), {
    output$txtmodel <- renderPrint({cat("No se ha generado el modelo.")})
  })
  
  observeEvent(updateData$grupos, {
    choices <- 1:length(updateData$grupos)
    updateSelectInput(session, "vci", choices = choices)
  })
  
  observeEvent(input$vci, {
    modelosrv$i <- as.numeric(input$vci)
  })
  
  # Generar modelo
  observeEvent(input$runModelo, {
    output$txtmodel <- renderPrint({
      datos      <- isolate(updateData$datos)
      variable   <- isolate(updateData$variable.predecir)
      cant.tt    <- isolate(updateData$numTT)
      grupos     <- isolate(updateData$grupos)
      
      tryCatch({
        auxmodelos <- lapply(1:cant.tt, function(vc) {
          train <- datos[grupos[[vc]][["train"]], ]
          formula <- as.formula(paste0(variable, "~ ."))
          generar.modelo(nombrePred, formula, train, input, variable)
        })
        modelosrv$modelos <- auxmodelos
        if(nombrePred == "regp") {
          updateNumericInput(session, "lambda", value = log(auxmodelos[[1]]$modelo$lambda.1se))
        }
        print(auxmodelos)
      }, error = function(e) {
        modelosrv$modelos <- NULL
        modelosrv$modelo  <- NULL
        modelosrv$i       <- 1
        print(e)
      }, warning = function(w) {
        modelosrv$modelos <- NULL
        modelosrv$modelo  <- NULL
        modelosrv$i       <- 1
        print(w)
      })
    })
  })
  
  observeEvent(c(modelosrv$modelos, input$aplicar, input$aplicarLambda), {
    cv_modelos <- modelosrv$modelos
    
    datos    <- isolate(updateData$datos)
    grupos   <- isolate(updateData$grupos)
    variable <- isolate(updateData$variable.predecir)
    vari     <- which(names(datos) == variable)
    lambda <- input$lambda
    if(is.null(lambda) | !is.numeric(lambda)) {
      lambda <- 0
    }
    #& !is.null(input$sel_cat) & !is.null(input$sel_corte)
    
    tryCatch({
      if(!is.null(cv_modelos)) {
        for (vc in 1:length(cv_modelos)) {
          modelo <- cv_modelos[[vc]]$modelo
          nombre <- cv_modelos[[vc]]$algoritmo
          
          if(nombrePred == "regp") {
            test  <- datos[grupos[[vc]][["test"]], ]
            test2 <- test[, -vari]
            test2 <- model.matrix(~., test2)[, -1]
            pred  <- list(prediction = predict(modelo, test2, s = exp(lambda)), 
                          var.pred = variable)
          } else if(nombrePred == "rdim") {
            test <- datos[grupos[[vc]][["test"]], ]
            ncomp <- modelo$optimal.ncomp
            auxp  <- predict(modelo, test, ncomp = ncomp)
            pred  <- list(prediction = auxp[, , 1], var.pred = variable)
          } else {
            test <- datos[grupos[[vc]][["test"]], ]
            pred <- predict(modelo, test)
          }
          
          indices <- traineR::general.indexes(test, pred)
          
          modelos[[nombrePred]][[nombre]][[vc]] <- list(
            nombre = nombre, modelo = modelo,
            pred = pred, indices = indices
          )
        }
        
        modelosrv$modelo <- modelos[[nombrePred]][[nombre]]
        modelosrv$i <- isolate(as.numeric(input$vci))
      }
    }, error = function(e) {
      print(e)
      modelos[[nombrePred]] <- NULL
    })
  })
  
  # Resumen variable a predecir
  output$VARP <- renderTable({
    datos <- updateData$datos
    var   <- updateData$variable.predecir
    lg    <- codedioma$idioma
    decs  <- updateData$decimals
    x     <- datos[, var]
    
    tryCatch({
      df <- data.frame(
        MIN = min(x), Q1 = quantile(x, prob = 0.25),
        Q3 = quantile(x, prob = 0.75), MIN = max(x)
      )
      df <- round(df, decs)
      
      colnames(df) <- c(tr("minimo",lg), tr("q1",lg), tr("q3", lg), tr("maximo", lg))
      return(df)
    }, error = function(e) {
      showNotification(paste0("Error (RL-06) : ", e), 
                       duration = 10, type = "error")
      return(NULL)
    })
  }, striped = TRUE, bordered = TRUE, spacing = 'l', width = '100%', align = 'c')
  
  output$RMSEBox <- renderValueBox({
    lng    <- codedioma$idioma
    modelo <- modelosrv$modelo[[modelosrv$i]]
    decs   <- updateData$decimals
    if(is.null(modelo)) {
      return(NULL)
    } else {
      RMSE <- round(modelo$indices$RMSE, decs)
      valueBox(RMSE, tr("RMSE", lng), icon = NULL, color = "yellow")
    }
  })
  
  output$MAEBox <- renderValueBox({
    lng    <- codedioma$idioma
    modelo <- modelosrv$modelo[[modelosrv$i]]
    decs   <- updateData$decimals
    if(is.null(modelo)) {
      return(NULL)
    } else {
      MAE <- round(modelo$indices$MAE, decs)
      valueBox(MAE, tr("MAE", lng), icon = NULL, color = "yellow")
    }
  })
  
  output$REBox <- renderValueBox({
    lng    <- codedioma$idioma
    modelo <- modelosrv$modelo[[modelosrv$i]]
    decs   <- updateData$decimals
    if(is.null(modelo)) {
      return(NULL)
    } else {
      RE <- round(modelo$indices$RE, decs)
      valueBox(RE, tr("ER", lng), icon = NULL, color = "yellow")
    }
  })
  
  output$CORBox <- renderValueBox({
    lng    <- codedioma$idioma
    modelo <- modelosrv$modelo[[modelosrv$i]]
    decs   <- updateData$decimals
    if(is.null(modelo)) {
      return(NULL)
    } else {
      COR <- round(modelo$indices$COR, decs)
      valueBox(COR, tr("correlacion", lng), icon = NULL, color = "yellow")
    }
  })
  
  # Tabla de la prediccion
  output$modeloPredTable <- DT::renderDataTable({
    datos  <- isolate(updateData$datos)
    grupos <- isolate(updateData$grupos)
    modelo <- modelosrv$modelo[[modelosrv$i]]
    test   <- datos[grupos[[modelosrv$i]][["test"]], ]
    var    <- isolate(updateData$variable.predecir)
    lng    <- codedioma$idioma
    decs   <- updateData$decimals
    
    real <- round(test[, var], decs)
    pred <- modelo$pred
    etqs <- c(tr("reald", lng), tr("pred", lng))
    tabla.pred(real, pred$prediction, etqs, decs)
  }, server = FALSE)
  
  # Update Coefficients tab
  output$rlCoefTable <- DT::renderDataTable({
    modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
    decs   <- updateData$decimals
    lang   <- codedioma$idioma
    
    tryCatch({
      if(!is.null(modelo)) {
        coeff <- modelo$coefficients
        df    <- data.frame(ID = names(coeff), coeff = coeff)
        df$coeff <- round(as.numeric(df$coeff), decs)
        colnames(df) <- c("ID", tr("coeff", lang))
        
        DT::datatable(df, rownames = FALSE, options = list(dom = "frtip"))
      } else{
        return(NULL)
      }
    }, error = function(e){
      showNotification(paste0("Error (RL-02) : ", e), duration = 10, type = "error")
      return(NULL)
    })
  }, server = F)
  
  # Plotear el arbol
  output$plot_tree <- renderPlot({
    tryCatch({
      modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
      tree_plot(modelo)
    }, error = function(e) {
      return(NULL)
    })
  })
  
  # Mostrar Reglas Arboles
  output$rules_tree <- renderPrint({
    modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
    varpred <- modelo$prmdt$var.pred
    
    tree_rules(modelo, varpred)
  })
  
  # Grafico de evolucion del error Bosques
  output$plot_error_rndf <- renderEcharts4r({
    tryCatch({
      modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
      #cod  <- paste0("### evolerror\n", plot.rf.error())
      #isolate(codedioma$code <- append(codedioma$code, cod))
      e_rf_error(modelo, strsplit(tr("numTree", codedioma$idioma), ':')[[1]])
    }, error = function(e) {
      print(e)
      return(NULL)
    })
  })
  
  # Grafico de importancia de variables Bosques
  output$plot_var_rndf <- renderEcharts4r({
    tryCatch({
      #cod  <- paste0("### docImpV\n", rf.importance.plot())
      #isolate(codedioma$code <- append(codedioma$code, cod))
      modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
      e_rndf_importance(modelo)
    }, error = function(e) {
      print(e)
      return(NULL)
    })
  })
  
  # Grafico de evolucion del error Potenciacion
  output$plot_error_boost <- renderEcharts4r({
    modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
    label  <- strsplit(tr("numTree", codedioma$idioma), ':')[[1]]
    
    tryCatch({
      e_boost_evol_error(modelo, label)
    }, error = function(e) {
      print(e)
      return(NULL)
    })
  })
  
  # Grafico de importancia de variables Potenciacion
  output$plot_var_boost <- renderEcharts4r({
    tryCatch({
      modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
      e_boost_importance(modelo)
    }, error = function(e) {
      return(NULL)
    })
  })
  
  # Genera el grafico de la red neuronal
  output$plot_nnet <- renderPlot({
    idioma <- codedioma$idioma
    tryCatch({
      modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
      hidden <- as.numeric(as.character(modelo$call$hidden)[-1])
      if((length(hidden) * sum(hidden)) <= 1500 & ncol(modelo$covariate) <= 20) {
        #cod <- ifelse(input$fieldCodeNnPlot == "", nn.plot(), input$fieldCodeNnPlot)
        nnet_plot(modelo)
      } else {
        showNotification(tr("bigPlot", idioma), duration = 10, type = "message")
        return(NULL)
      }
    }, error = function(e){
      return(NULL)
    })
  })
  
  # Grafico de los Lambdas
  output$plot_regp_lambda <- renderEcharts4r({
    idioma <- codedioma$idioma
    scales <- isolate(as.logical(input$scales))
    alpha  <- isolate(input$alpha)
    
    tryCatch({
      modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
      e_posib_lambda(modelo, labels = c(tr("superior", idioma), tr("inferior", idioma), tr("lambda", idioma)))
    }, error = function(e) { 
      showNotification(paste0("Error (R/L) : ", e), duration = 15, type = "error")
      return(NULL)
    })
  })
  
  observeEvent(input$calcularLambda, {
    modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
    updateNumericInput(session, "lambda", value = log(modelo$lambda.1se))
  })
  
  # Texto de los Betas
  output$txtBetas <- renderPrint({
    tryCatch({
      lambda <- isolate(input$lambda)
      if(is.null(lambda)) {
        lambda <- 0
      }
      modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
      
      res <- coef(modelo, s = lambda)
      print(res[, 1])
    },
    error = function(e){ 
      return(NULL)
    })
  })
  
  # Grafico de los coeficientes Lambdas
  output$plot_regp_coeff <- renderEcharts4r({
    lambda <- isolate(input$lambda)
    if(is.null(lambda)) {
      lambda <- 0
    }
    modelo <- modelosrv$modelo[[modelosrv$i]]$modelo
    
    tryCatch({
      e_coeff_lambda(modelo, lambda, tr("lambda", codedioma$idioma))
    },
    error = function(e){ 
      showNotification(paste0("Error (R/L) : ", e), duration = 15, type = "error")
    })
  })
  
  # Grafico Reducción de la dimension (RMSE)
  output$plot_rmse <- renderEcharts4r({
    tryCatch({
      idioma  <- codedioma$idioma
      modelo  <- modelosrv$modelo[[modelosrv$i]]$modelo
      ncomp   <- as.numeric(modelo$optimal.ncomp)
      titulos <- c(tr("RMSE", idioma), tr("ncomp", idioma))
      e.rdim.rmse(modelo, ncomp, titulos)
    }, error = function(e) {
      showNotification(paste0(e), duration = 10, type = "error")
      return(NULL)
    })
  })
  
  # Grafico Reducción de la dimension (VARE)
  output$plot_vare <- renderEcharts4r({
    tryCatch({
      idioma   <- codedioma$idioma
      modelo   <- modelosrv$modelo[[modelosrv$i]]$modelo
      titulos  <- c(tr("VarExp", idioma), tr("ncomp", idioma))
      ncomp <- as.numeric(modelo$optimal.ncomp)
      e.rdim.vare(modelo, ncomp, titulos)
    }, error = function(e) {
      showNotification(paste0(e), duration = 10, type = "error")
      return(NULL)
    })
  })
  
  # Variación del Error
  output$VARE <- renderEcharts4r({
    input$aplicar2
    modelo <- modelosrv$modelo
    lng    <- codedioma$idioma
    decs   <- updateData$decimals
    ind    <- isolate(input$sel_ind_err)
    df     <- calc_cross_error_tt(modelo, ind)
    df     <- round(df, decs)
    
    tiulos <- c(tr("numExp", lng), tr(ind, lng))
    
    e_var_error(df, T, tiulos)
  })
}

## To be copied in the UI
# mod_train_test_ui("train_test_ui_1")

## To be copied in the server
# callModule(mod_train_test_server, "train_test_ui_1")

Try the regressoR package in your browser

Any scripts or data that you put into this service are public.

regressoR documentation built on April 3, 2025, 9:32 p.m.