Shiny中使用between函数提取数值时触发错误的排查
Shiny应用filter报错问题排查
编辑(问题尚未解决)
以下R Shiny代码运行时出现错误:
# Possible result with num_src() == 6 & num_ong() == 4 donnees = tribble( ~epci.res,~annee,~an_muta,~natloc3,~n,~pct,~total Bordeaux Métropole,2015,FALSE,Appart,8175,0.7456220357533747,10964 Bordeaux Métropole,2015,FALSE,Maison,2789,0.2543779642466253,10964 Bordeaux Métropole,2015,TRUE,Appart,755,0.6869881710646042,1099 Bordeaux Métropole,2015,TRUE,Maison,344,0.3130118289353958,1099 Bordeaux Métropole,2016,FALSE,Appart,7968,0.742937062937063,10725 Bordeaux Métropole,2016,FALSE,Maison,2757,0.257062937062937,10725 Bordeaux Métropole,2016,TRUE,Appart,577,0.698547215496368,826 Bordeaux Métropole,2016,TRUE,Maison,249,0.3014527845036319,826 Bordeaux Métropole,2017,FALSE,Appart,10306,0.7248048385962444,14219 Bordeaux Métropole,2017,FALSE,Maison,3913,0.2751951614037556,14219 Bordeaux Métropole,2017,TRUE,Appart,922,0.5952227243382827,1549 Bordeaux Métropole,2017,TRUE,Maison,627,0.4047772756617172,1549 Bordeaux Métropole,2018,FALSE,Appart,8399,0.7325774095071959,11465 Bordeaux Métropole,2018,FALSE,Maison,3066,0.2674225904928042,11465 Bordeaux Métropole,2018,TRUE,Appart,1867,0.7194605009633911,2595 Bordeaux Métropole,2018,TRUE,Maison,728,0.2805394990366089,2595 Bordeaux Métropole,2019,FALSE,Appart,8368,0.7362308639802921,11366 Bordeaux Métropole,2019,FALSE,Maison,2998,0.2637691360197079,11366 Bordeaux Métropole,2019,TRUE,Appart,1076,0.662969808995687,1623 Bordeaux Métropole,2019,TRUE,Maison,547,0.337030191004313,1623 Bordeaux Métropole,2020,FALSE,Appart,13438,0.8117675486287302,16554 Bordeaux Métropole,2020,FALSE,Maison,3116,0.1882324513712698,16554 Bordeaux Métropole,2020,TRUE,Appart,1118,0.6901234567901234,1620 Bordeaux Métropole,2020,TRUE,Maison,502,0.3098765432098766,1620 Bordeaux Métropole,2021,FALSE,Appart,13308,0.8090461426226518,16449 Bordeaux Métropole,2021,FALSE,Maison,3141,0.1909538573773482,16449 Bordeaux Métropole,2021,TRUE,Appart,1078,0.6633846153846154,1625 Bordeaux Métropole,2021,TRUE,Maison,547,0.3366153846153846,1625 CA Rochefort Océan,2015,FALSE,Appart,709,0.1840124578250714,3853 CA Rochefort Océan,2015,FALSE,Maison,3144,0.8159875421749286,3853 CA Rochefort Océan,2015,TRUE,Appart,46,0.1957446808510638,235 CA Rochefort Océan,2015,TRUE,Maison,189,0.8042553191489362,235 CA Rochefort Océan,2016,FALSE,Appart,751,0.1932081296629792,3887 CA Rochefort Océan,2016,FALSE,Maison,3136,0.8067918703370208,3887 CA Rochefort Océan,2016,TRUE,Appart,82,0.2867132867132867,286 CA Rochefort Océan,2016,TRUE,Maison,204,0.7132867132867133,286 CA Rochefort Océan,2017,FALSE,Appart,834,0.2061804697156984,4045 CA Rochefort Océan,2017,FALSE,Maison,3211,0.7938195302843016,4045 CA Rochefort Océan,2017,TRUE,Appart,83,0.2492492492492492,333 CA Rochefort Océan,2017,TRUE,Maison,250,0.7507507507507507,333 CA Rochefort Océan,2018,FALSE,Appart,750,0.1975243613378983,3797 CA Rochefort Océan,2018,FALSE,Maison,3047,0.8024756386621017,3797 CA Rochefort Océan,2018,TRUE,Appart,119,0.2997481108312343,397 CA Rochefort Océan,2018,TRUE,Maison,278,0.7002518891687658,397 CA Rochefort Océan,2019,FALSE,Appart,742,0.1951604418726986,3802 CA Rochefort Océan,2019,FALSE,Maison,3060,0.8048395581273015,3802 CA Rochefort Océan,2019,TRUE,Appart,61,0.2663755458515284,229 CA Rochefort Océan,2019,TRUE,Maison,168,0.7336244541484717,229 CA Rochefort Océan,2020,FALSE,Appart,905,0.224009900990099,4040 CA Rochefort Océan,2020,FALSE,Maison,3135,0.775990099009901,4040 CA Rochefort Océan,2020,TRUE,Appart,36,0.2236024844720497,161 CA Rochefort Océan,2020,TRUE,Maison,125,0.7763975155279503,161 CA Rochefort Océan,2021,FALSE,Appart,1428,0.304932735426009,4683 CA Rochefort Océan,2021,FALSE,Maison,3255,0.695067264573991,4683 CA Rochefort Océan,2021,TRUE,Appart,100,0.3937007874015748,254 CA Rochefort Océan,2021,TRUE,Maison,154,0.6062992125984252,254 ) ui <- page_sidebar( sidebar = sidebar( position = 'right', helpText("Veuillez remplir les champs suivants :"), # Sélecteur de la source et de la variable selectInput( inputId = "src", label = "Source :", choices = c( "Fidéli", "Filocom" ) ), selectInput( inputId = "var", label = "Indicateur :", choices = choix ), selectInput( inputId = "muta", label = "Filtrez selon la dernière année de mutation du local :", choices = c( "Ensemble des logements" = F, "Logements ayant muté cette année" = T) ), uiOutput('an'), selectInput( inputId = "epci", multiple = TRUE, label = "EPCI(s) :", choices = EPCI, selected = "CA de La Rochelle" ) ) server <- function(input, output, session) { # Nom de la source num_src <- reactive({ case_match(input$src, 'Fidéli' ~ 0, 'Filocom' ~ 6) |> as.integer() }) # Numéro de l'onglet de l'indicateur sélectionné num_ong <- reactive({case_match( str_sub(input$var,1,1), 'S' ~ 1, 'Â' ~ 2, 'D' ~ 3, 'O' ~ 4, 'N' ~ 5, 'C' ~ 6) }) # Tableau des dates min et max des 2 sources dates <- reactive({tribble( ~src, ~muta, ~y_min, ~y_max, ~intvl, 0, c(T,F), 2015,2021,1, 6,T,2013,2020,1, 6,F,2014,2020,2, 0,c(T,F), 2020,2021,1 ) |> mutate(ong = case_when( y_min == 2020 ~ list(6L), T ~ list(1:5))) |> unnest(muta) |> unnest(ong) |> filter(src == num_src() & muta == input$muta & ong == as.integer(num_ong())) }) y_min <- reactive({pull(dates(),y_min)}) y_max <- reactive({pull(dates(),y_max)}) intvl <- reactive({pull(dates(),intvl)}) # Réglage de la barre de sélection des années output$an <- renderUI({ sliderInput( inputId = "an", label = "Choisissez une période :", sep = '', step = intvl, min = y_min(), max = y_max(), value = c(y_min(), y_max()) ) }) an_min <- input$an[[1]] an_max <- input$an[[2]] data <- donnees[[num_src() + num_ong()]] |> filter(an_muta == input$muta & between(annee,an_min,an_max) & #ERRORRR!! epci.res %in% input$epci) } shinyApp(ui, server)
错误提示:
Error in filter: ℹ In argument: `an_muta == input$muta & annee >= an_min & annee <= an_max`. Caused by error: ! `..1` must be of size 756 or 1, not size 0.
已通过str()函数确认between()函数的左右参数均为整数,参数来自Shiny输入。添加dates tibble之前代码可正常运行,请问该错误的原因是什么?有什么解决思路?
错误原因分析
- 动态输入未被正确响应:
an_min和an_max直接从input$an赋值,但input$an是动态生成的UI元素,初始化阶段可能未创建,导致这两个变量值为空(长度0),传入filter后引发尺寸不匹配。 datesreactive返回空表:当num_src()、input$muta、num_ong()的组合在dates过滤后无匹配行时,y_min()、y_max()会返回空向量,导致sliderInput参数异常,进一步让input$an无法正常取值。- 数据索引逻辑错误:
donnees是单个tibble,但代码用donnees[[num_src() + num_ong()]]按列表索引取值,会返回空对象,后续filter自然报错。
解决思路
- 将依赖输入的变量转为reactive表达式:确保变量能响应输入变化,且在输入就绪后才计算:
an_min <- reactive({ input$an[[1]] }) an_max <- reactive({ input$an[[2]] }) data <- reactive({ # 确保所有依赖项就绪 req(num_src(), num_ong(), an_min(), an_max(), input$muta, input$epci) # 修正索引逻辑,直接使用donnees donnees %>% filter(an_muta == input$muta, between(annee, an_min(), an_max()), epci.res %in% input$epci) }) - 修复
dates表逻辑:清理重复行,确保所有输入组合都有匹配项,避免返回空表:dates <- reactive({ tribble( ~src, ~muta, ~y_min, ~y_max, ~intvl, 0, TRUE, 2015,2021,1, 0, FALSE, 2015,2021,1, 6, TRUE, 2013,2020,1, 6, FALSE, 2014,2020,2, 0, TRUE, 2020,2021,1, 0, FALSE, 2020,2021,1 ) %>% mutate(ong = case_when( y_min == 2020 ~ list(6L), TRUE ~ list(1:5) ))
相关产品推荐
相关产品推荐

