【问题标题】:Shiny - Reactive filter function issueShiny - 反应式过滤器功能问题
【发布时间】:2021-03-06 02:03:57
【问题描述】:

希望有人能帮助解决这个棘手的问题:Shiny 应用程序在 Excel 模板下完美运行,但是当用户加载新文件并刷新计算时,出现此错误:

Warning: Unknown or uninitialised column: `Distribution`.
Warning: Unknown or uninitialised column: `Distribution`.
Warning: Unknown or uninitialised column: `Distribution`.
Warning: Error in : Problem with `filter()` input `..1`.
x Input `..1` must be of size 3 or 1, not size 0.
i Input `..1` is `!is.na(rv$RRDTRaw$Likelihood) & !is.na(rv$RRDTRaw$Distribution)`.
  59: <Anonymous>

此问题仅在代码中最后一个带有过滤功能的“观察”功能处于活动状态时显示。如果我评论它,问题就消失了。 见下方代码:

## LIBRARIES
        library(tidyverse)
        library(stats)
        library(data.table)
        library(triangle)
        library(base)
        library(matrixStats)
        library(ggplot2)
        library(ggthemes)
        library(readxl)
        library(httr)
        library(shiny)

## DEFINITIONS

    vQuantiles <- c(P00 = 0, P05 = .05, P50 = .50, P80 = .80, P95 = .95, P100 = 1)
        vtQuantiles <- names(vQuantiles)

    MCScenarioTotals <- list()
    MCTotalsQuantiles <- list()
    MCRecordsQuantiles <- list()
    MCRecordsQuantilesTop10 <- list()

## LOAD RR TEMPLATES

    ExcelTemplate <- tempfile(fileext = ".xlsx")
    GET(url = "https://www.openmontecarlo.com/SampleS.xlsx",write_disk(ExcelTemplate))
    defaultRR <- read_excel(ExcelTemplate)

## DEFINE UI

ui <-

fluidPage(
    hr(),
    h1("Monte Carlo Simulation",align = "center"),

    fluidRow(
        hr(),
        column(3,
            checkboxGroupInput("ISvModels", label = h3("Step 1:",br(),"Select which Models to Run"), 
            choices = list(
            "100 Scenarios" = 100,
            "1000 Scenarios" = 1000,
            "5000 Scenarios" = 5000,
            "10000 Scenarios" = 10000),
            selected = 100),offset = 1
        ),

        column(7,
            selectInput("templateSelection",h3("Step 2:",br(),"Select an existing Risk Register sample"),
                c(1,2,3,4),selected = 3,multiple = FALSE,selectize = TRUE,width = NULL,size = NULL),
            
            fileInput("userExcel", h3("Or upload your own Risk Register"),accept = ".xlsx"),
            offset = 1,
        ),
    ),
    hr(),

    fluidRow(
        column(5,
            h3("Step 3: Click to run the models"),
            offset = 1,
        ),

        column(6,
            br(),
            actionButton(inputId = "Refresh", label = "Run Simulation",
            ),
            offset = 0,
        ),
    ),
    hr(),

    mainPanel(  

        h3(strong("Risk Register - Imported Data")),
        br(),
        dataTableOutput("SRRImport"),

        h3(strong("Risk Register - Raw Data")),
        br(),
        dataTableOutput("SRRDTRaw"),

        h3(strong("Risk Register - Invalid Likelihood Data")),
        br(),
        dataTableOutput("SLikelihoodQADrop"),

        h3(strong("Risk Register - Invalid Impact Data")),
        br(),
        dataTableOutput("SImpactQADrop"),

        h3(strong("Risk Register - Valid Data")),
        br(),
        dataTableOutput("SRRDT"),

    )
)

server <- function(input, output) {

## CREATE DEFAULT RR AND REACTIVE VARIABLES

rv <- reactiveValues(
    inputRR = tempfile(fileext = ".xlsx"),
    inputPath = NULL,
    vModels = c(100),
    RRImport = defaultRR,
    RRuserExcel = data.frame(),
    RRDTRaw = data.frame(),
    LikelihoodQADrop = data.frame(),
    ImpactQADrop = data.frame(),
    RRDT = data.frame(),
    nDrop = 0,
    nRisks = 1,
    RRDTLong = data.frame()
    )

# SHINY INPUT REFRESH

    observeEvent(input$Refresh,{if (is.null(input$userExcel)) {rv$RRImport <- defaultRR}
        else {
        rv$inputPath <- input$userExcel
        output$SinputPath <- renderPrint({rv$inputPath[,4]})
        rv$inputRR <- read_excel(paste0(rv$inputPath[,4]))
        rv$RRImport <- rv$inputRR
        }
    })

# data.frame(suppressWarnings(

    output$SRRImport <- renderDataTable({rv$RRImport})

    observe({rv$nRisksImported <- nrow(rv$RRImport)})
        output$SnRisksImported <- renderPrint({rv$nRisksImported})

## PROCESS MODELS INPUT

    observeEvent(input$Refresh,{rv$vModels <- as.numeric(unlist(input$ISvModels))})
        output$vModelsText <- renderPrint({unlist(rv$vModels)})

    qtModels <- reactive({length(unlist(rv$vModels))})
        output$qtModelsText <- renderPrint({unlist(qtModels())})

    vtModels <- reactive({paste0("M",1:qtModels()," n = ",rv$vModels," scenarios")})
        output$vtModelsText <- renderPrint({unlist(vtModels())})

## RR RAW

    observe({rv$RRDTRaw <- rv$RRImport})
    observe({rv$RRDTRaw$Likelihood <- suppressWarnings(as.numeric(rv$RRDTRaw$Likelihood))})
    observe({rv$RRDTRaw$Min <- suppressWarnings(as.numeric(rv$RRDTRaw$Min))})
    observe({rv$RRDTRaw$ML <- suppressWarnings(as.numeric(rv$RRDTRaw$ML))})
    observe({rv$RRDTRaw$Max <- suppressWarnings(as.numeric(rv$RRDTRaw$Max))})
      
## QUALITY CHECK LIKELIHOOD

    observe({rv$RRDTRaw$Likelihood <- ifelse (rv$RRDTRaw$Likelihood <=0 | rv$RRDTRaw$Likelihood >=100,NA,rv$RRDTRaw$Likelihood)})

    observe({rv$LikelihoodQADrop <- rv$RRImport[which(is.na(rv$RRDTRaw$Likelihood)),]})
        output$SLikelihoodQADrop <- renderDataTable({rv$LikelihoodQADrop})

## CLASSIFY AND QUALITY CHECK DISTRIBUTIONS

    observe({rv$RRDTRaw <- mutate(rv$RRDTRaw,Distribution = case_when(is.na(rv$RRDTRaw$Min) & is.na(rv$RRDTRaw$Max) & !is.na(rv$RRDTRaw$ML) ~ "Single Point",
                                        is.na(rv$RRDTRaw$ML) & !is.na(rv$RRDTRaw$Min) & !is.na(rv$RRDTRaw$Max) & rv$RRDTRaw$Min<rv$RRDTRaw$Max ~ "Uniform",
                                        !is.na(rv$RRDTRaw$Min) & !is.na(rv$RRDTRaw$Max) & !is.na(rv$RRDTRaw$ML) & rv$RRDTRaw$Min<rv$RRDTRaw$ML & rv$RRDTRaw$ML<rv$RRDTRaw$Max ~ "3 Points"))
            })
        output$SRRDTRaw <- renderDataTable({rv$RRDTRaw})

    observe({rv$ImpactQADrop <- rv$RRImport[which(is.na(rv$RRDTRaw$Distribution)),]})
        output$SImpactQADrop <- renderDataTable({rv$ImpactQADrop})

## DROP + DECLARE NAs AND PROCEED + PRINT THE RISK REGISTER

    observe({rv$RRDT <- filter(rv$RRDTRaw, !is.na(rv$RRDTRaw$Likelihood) & !is.na(rv$RRDTRaw$Distribution))})

}

# Run the app ----
shinyApp(ui = ui, server = server)

很难理解这些函数如何为第一个自动加载的文件工作,以及为什么用户输入的文件会破坏应用程序。即使我上传与模板相同的文件,也会发生这种情况。

希望您能提供帮助。谢谢!!

【问题讨论】:

  • 在最后一次观察中尝试dplyr::filter(...),因为您可能有来自其他包的过滤器。
  • 嗨@YBS。这是一个非常好的电话,谢谢!不幸的是,我仍然遇到相同的情况:它与最初加载的 Excel 文件完美运行,但在我上传新文件并单击运行后我收到错误消息,即使我上传了相同的模板 Excel 文件。这怎么可能???
  • 嘿,再次感谢您的建议。相信我,我尝试了各种变通方法,将单独的 if 函数和其他逻辑运算符更改为 is.na、!is.na...
  • 还尝试将过滤器功能替换为“complete.cases”和“which”,但都给出了完全相同的错误消息。问题的根源似乎在于使用 mutate 创建 Distribution 列以及此“未初始化”列生成的任何含义,这似乎是 Shiny 的常见问题,尤其是在使用 mutate 时。因为它只发生在用户输入文件中,我也想象我的反应值声明中可能存在一些错误,但我花了很多时间尝试不同的方法,它们都适用于模板文件,但与用户输入文件中断

标签: r filter shiny xlsx reactive


【解决方案1】:

您的read_excel 不适用于用户输入文件,因为它只是一个路径。试试read_xlsx,如下图。

observeEvent(input$Refresh,{if (is.null(input$userExcel)) {rv$RRImport <- defaultRR}
    else {
      inFile <- input$userExcel
      rv$inputPath <- inFile
      output$SinputPath <- renderPrint({rv$inputPath[,4]})
      #rv$inputRR <- read_excel(paste0(rv$inputPath[,4]))
      rv$inputRR <- read_xlsx(inFile$datapath, sheet =  1)
      rv$RRImport <- rv$inputRR
    }
  })

【讨论】:

  • 嗨 YBS,再次感谢您关注这个!我试过这个,它和reas_excel有同样的问题:加载模板文件时两个函数都工作,当用户输入文件加载相同的消息时都中断:x输入..1必须大小为3或1,大小不是 0。我很确定它在操作 data.frame 的过滤器函数中,因为如果我评论它一切正常,并且两个文件都被上传并完美处理到应该应用过滤器的位置。然而,再尝试一件事并确保它运行正常是非常好的。再次感谢!
  • 使用dplyr::filter(...)read_xlsx,对我来说效果很好。我刚刚下载了您自动加载的相同文件,并将其用作用户文件。
  • 伙计,我刚刚在服务器上运行了它,它工作了!!!很高兴现在继续使用我的代码。我的 RStudio 中的某些东西仍然崩溃,我将重新安装它。也感谢您检查并让我知道它有效。不能告诉你这有多棒,非常感谢你追逐这个!!!万事如意!
猜你喜欢
  • 2018-10-11
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 2021-05-19
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
  • 2017-08-14
相关资源
最近更新 更多