Почему блестящее приложение работает локально, а не на сервере? - PullRequest
0 голосов
/ 17 апреля 2020

Я предполагаю, что это дублирующий вопрос (извините заранее), но я не могу решить эту проблему. Я создал блестящее приложение, которое реализует модель случайного леса (партийный пакет), возвращая результаты с помощью пакета caret и визуализируя дерево условных помех с помощью функции ctree. Приложение отлично работает локально. Однако, когда я пытаюсь опубликовать sh, ничего не выводится, и я получаю ошибку "Произошла ошибка. Проверьте ваши журналы или свяжитесь с автором приложения для уточнения." Что мне здесь не хватает?

Данные, которые я использую для модели, получены из CSV-файла, хранящегося в учетной записи Dropbox. Возможно, это может быть проблемой? Сначала я использовал RData и переключился на CSV-файл, так как это, как представляется, чаще используется с глянцевым.

Я следовал шагам, описанным на: https://support.rstudio.com/hc/en-us/articles/229848967-Why-does-my-app-work-locally-but-not-on-shinyapps-io-, чтобы проверить, удалось ли это восстановить вопрос. Я перезапустил R и компьютер. Это не сработало.

  • Нет кода или данных, хранящихся в локальной среде при локальном запуске.

  • Все пакеты загружаются через библиотеку ().

  • Я загружаю данные через относительный путь df <- read.csv ("data / df.csv"). Все файлы хранятся в карте с именем shinyapp как app.R и df.csv в данных файла. </p>

Набор данных относительно большой, поэтому я не могу отобразить его здесь, но я создал фиктивный набор данных, который можно использовать для запуска приложения.

library(shiny)
library(party)
library(caret)
#==============================================================================
#Use dummy dataset in stead of original data
#df <- read.csv("data/df.csv")
#df <- df[df$Taxon %in% names(table(df$Taxon))[table(df$Taxon) >= 50],]

#Create dummy dataset
df  <- data.frame(Sample = 1:500, Taxon = paste0("spec", rbinom(n = 500, 2, 0.5)), SO4 = rnorm(500, 300, 50), pH = rnorm(500, 7, 1), NO3 = rnorm(500, 10, 3))

ui <- fluidPage(
  titlePanel("Random Forest classification"),
  sidebarPanel(
    selectInput(inputId = "Spec", label = "Select species:", unique(df$Taxon)),
    selectInput(inputId = "NAN", label = "Select how to use data:", c("All data (Also NAs)", "Complete data (No NAs)")),
    numericInput(inputId = "SO4", label = "Choose value for SO4 (mg/l)", value = median(df$SO4, na.rm = T), min = 0, max = 15000),
    numericInput(inputId = "pH", label = "Choose value for pH", value = median(df$pH, na.rm = T), min = 5, max = 10),
    numericInput(inputId = "NO3", label = "Choose value for NO3 (mg/l)", value = median(df$NO3, na.rm = T), min = 0, max = 50),
    h3("Validation parameters"),
    textOutput("Validation"),
    h3("Voting percentage"),
    textOutput("Votingperc"),
    h3("Remarks"),
    h5("Note that every time the output of the model is different from
       the previous. Samples with the absence of species are more
       prevalent. Therefore, Every time the code is run, samples where a species
       was present are the same. However, samples with absences are randomly 
       selected in equall amount and combines this with samples where the. 
       species was present Further, the random forest model randomly creates 
       trees by bootstrapping the dataset a 100 times. Each time a different 
       model is created. This model is a course estimation, since many more 
       important factors are absent. Validation of the model is performed by 
       training the model on 75% of the dataset and validating on the other 25%. 
       The predicting model is based on the total dataset. The Error: 
       replacement has 1 row, data has 0, occurs when the data for a species
       has no measurements if complete data (without NAs) is used.")),
  mainPanel(plotOutput("Imp"),
            plotOutput("Tree")))

server <- function(input,output){

  #Create model dataset
  modpred           <- reactive({
    present         <- df[df$Taxon == input$Spec,]
    present$Spec    <- 1
    df1             <- df[!duplicated(df$Sample),]
    df1             <- df1[!df1$Sample %in% present$Sample,]

    if(input$NAN == "Complete data (No NAs)"){
      present <- na.omit(present)
      df1     <- na.omit(df1)}

    if((nrow(df)-nrow(present)) > nrow(present)){
      absent        <- df1[sample(1:nrow(df1), nrow(present), replace = F),]}
    else{
      absent        <- df1[sample(1:nrow(df1), nrow(present), replace = T),]}
    absent$Spec     <- 0
    model.data      <- rbind(present, absent)
    model.data$Spec <- as.factor(model.data$Spec)

    #Select 75% as training data
    prestrain       <- present[sample(1:nrow(present), floor(nrow(absent)*0.75), replace = F),]
    abstrain        <- absent[sample(1:nrow(absent), floor(nrow(present)*0.75), replace = F),]
    train.data      <- rbind(prestrain, abstrain)
    train.data$Spec <- as.factor(train.data$Spec)

    #Select the other 25% as validation data
    val.data        <- model.data[!rownames(model.data) %in% rownames(train.data),]

    #Create nice conditional interference tree on all data
    ct              <- party::ctree(Spec~SO4+pH+NO3, data = model.data)

    #Train and validate model
    train.model     <- party::cforest(Spec~SO4+pH+NO3, data=train.data, controls = party::cforest_classical(mtry = 1, ntree = 100))
    validation.mod  <- predict(train.model, newdata = val.data)
    conf.mat.val    <- table(val.data$Spec, predict(train.model, newdata = val.data))
    val.results     <- caret::confusionMatrix(conf.mat.val)
    sumval          <- paste0("AUC=", round(val.results$overall[1],2), " (LCI=", round(val.results$overall[3],2),"; ",
                              "HCI=", round(val.results$overall[4],2), "), ",
                              "Cohen's kappa=", round(val.results$overall[2],2), ", ",
                              "n-validation=", nrow(val.data), ", ", "n-training=", nrow(train.data), ", ", "n-total (model)=", nrow(model.data))

    #Extract relative importance parameters
    relimp          <- as.data.frame(party::varimp(train.model))
    relimp          <- cbind.data.frame(rownames(relimp), relimp)
    colnames(relimp)<-c("Parameter", "Relative importance")
    rownames(relimp)<- NULL
    relimp[,2]      <- relimp$`Relative importance`/sum(relimp$`Relative importance`)*100
    relimp          <- relimp[order(-relimp$`Relative importance`),]

    #Apply model on data input user interface
    model           <- party::cforest(Spec~SO4+pH+NO3, data=model.data, controls = party::cforest_classical(mtry = 1, ntree = 100))
    pred.data       <- setNames(data.frame(as.numeric(input$SO4), as.numeric(input$pH), as.numeric(input$NO3)), c("SO4", "pH", "NO3"))
    pred            <- predict(model, newdata = pred.data, type = "prob")
    prob            <- paste0("Voting percentage (Probability of presence) = ", round(pred$`1`[2]*100,0),"%", ",", 
                              " Majority vote indicates = ", ifelse(pred$`1`[2] > 0.5, "Present", "Absent"))

    combo <- list(Probability = prob, Validation = sumval, Tree = ct, Importance = relimp)})

  output$Votingperc <- renderText({
    combo <- modpred()
    combo$Probability})

  output$Validation <- renderText({
    combo <- modpred()
    combo$Validation})

  output$Imp <- renderPlot({
    combo <- modpred()
    bar   <- combo$Imp
    barplot(bar$`Relative importance`,
            names.arg = bar$Parameter, ylab = "Relative importance (%)")})

  output$Tree <- renderPlot({
    combo <- modpred()
    plot(combo$Tree, inner_panel=node_inner(combo$Tree, pval = FALSE))})

}

shinyApp(ui,server)

Заранее благодарен за помощь.

...