【问题标题】:Shiny reactive function is not updating as expected闪亮的反应功能没有按预期更新
【发布时间】:2015-02-16 18:39:01
【问题描述】:

原问题贴在这里: Shiny reactive Unexpected Behavior
该问题正在此处重新发布,以尝试改进之前在上面提供的链接中发布的原始问题,因为我无法获得任何帮助。

目标:简而言之,此应用程序的目的是允许用户根据提供的各种输入对数据帧中提供的数据进行搜索、过滤、切片和切块给用户。

作为server 函数的一部分,定义了一个名为index 的反应函数来查找与用户输入对应的索引。反应函数index 使用grepwhich 函数来定位数据帧df 中的相应索引。

我已经包含了一个可重现的代码,并尝试在适当的情况下包含 cmets。

关于代码的进一步解释:
这个问题的标题只是我自己的猜测,它基于index中的代码是正确的假设。 index 中的代码可能存在根本问题,而 index 函数的反应性不一定。为了测试这一点,作为server 函数的一部分,我包含了一个函数printIndex 以打印index 的结果以确保它正常工作。

我亲自尝试将ind.jind.cind.lind.dind.sind.all 的结果分别打印到控制台,它们似乎都产生了正确的结果.但是,当我测试ind 的结果时,它并不完全符合我的预期,所以我想知道是反应性还是代码行有问题。 ind 打算做的是获取存储在ind.all 中的所有查找索引的列表,并递归应用intersect 函数以从ind.all 中的所有子列表中查找公共元素。

如上所述,index 函数适用于单个过滤器。但是,当我为所有索引输入值时,作为用户,该函数不会按预期更新为正确的索引列表。例如,您可以尝试在Job textInput 中输入“application”,在Company selectizeInput 中输入“Gas Drive Global”,在Location textInput 同时点击Search!。您会看到数据表没有返回任何结果,而这显然对应于数据框df 的第一行。

#Load required packages
ListofPackages= c('shiny','ggplot2','scales')
lapply(ListofPackages,require,character.only=TRUE)

#Define the dataframe on which the search will be performed
df <- data.frame(Job=c('Applications Engineer ââ¬â Gas Drive',
                       'Engineer, Operations',
                       'Project Engineer',
                       'Project Engineer (Oil & Gas)',
                       'Project Engineer',
                       'Junior Engineer',
                       'Engineer, Operations',
                       'Research and Development (R&D) Junior Engineer',
                       'JUNIOR QUALITY ENGINEER',
                       'Junior Systems Design and Support Engineer',
                       'Mechanical Engineer Calgary, AB',
                       'Applications Engineer',
                       'Project Engineer',
                       'Pipeline Engineer',
                       'Development Engineer',
                       'Specialist Engineering Finance',
                       'Mechanical Engineer - Sudbury',
                       'Project Cost Analyst (12 month term)',
                       'Project Controls Functional Analyst',
                       'Project Controls Professionals'),
             Company=c('Gas Drive Global',
                       'Agrium Wholesale',
                       'City of Calgary',
                       'Stantec',
                       'Shell',
                       'Canadian National Railway',
                       'Pembina Pipeline Corporation',
                       'Velan Inc.',
                       'G.W. Goudreau Personnel Services Ltd',
                       'Stratified Automotive Controls',
                       'Pason Systems Corp.',
                       'Howden',
                       'Plains Midstream Canada',
                       'Amec Foster Wheeler',
                       'Red Bend Software',
                       'Canadian Pacific',
                       'GENIVAR',
                       'Thales',
                       'AltaGas Ltd.','BEMAC Construction Corp.'),
            Location=c('Calgary',
                      'Redwater',
                      'Calgary',
                      'Edmonton',
                      'Sarnia',
                      'Montréal',
                      'Calgary',
                      'Montréal',
                      'Windsor',
                      'Vancouver',
                      'Calgary',
                      'Winnipeg',
                      'Calgary',
                      'Calgary',
                      'Engineer',
                      'Calgary',
                      'Greater Sudbury',
                      'Ottawa',
                      'Calgary',
                      'Calgary'),
              Posted=c(1,
                       1,
                       1,
                       2,
                       2,
                       1,
                       4,
                       5,
                       6,
                       4,
                       1,
                       5,
                       5,
                       3,
                       1,
                       1,
                       15,
                       1,
                       1,
                       13),
             Source=c('Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed',
                      'Indeed'),
                url=c('http://ca.indeed.com/rc/clk?jk=2371e16aab902f84',
                      'http://ca.indeed.com/rc/clk?jk=428facb738edd397',
                      'http://ca.indeed.com/rc/clk?jk=e15d8fe4d362279b',
                      'http://ca.indeed.com/rc/clk?jk=28c1464fd4e28b24',
                      'http://ca.indeed.com/rc/clk?jk=736ec57bf6902b93',
                      'http://ca.indeed.com/rc/clk?jk=bdc9999eae922645',
                      'http://ca.indeed.com/rc/clk?jk=3a4588fca0e600b1',
                      'http://ca.indeed.com/rc/clk?jk=71f1abcd100850c6',
                      'http://ca.indeed.com/cmp/G.W.Goudreau-Personnel-Services-Ltd/jobs/Junior-Quality-Engineer-3237601a1f3d3abc?r=1',
                      'http://ca.indeed.com/cmp/Stratified-Automotive-Controls/jobs/Junior-System-Design-Support-Engineer-1d916a435e69b8ce?r=1',
                      'http://ca.indeed.com/rc/clk?jk=fca9a784a37ece8a',
                      'http://ca.indeed.com/rc/clk?jk=b2d0975c638c03a8',
                      'http://ca.indeed.com/rc/clk?jk=c92725272c5f9ced',
                      'http://ca.indeed.com/rc/clk?jk=cd97c050df64787c',
                      'http://ca.indeed.com/rc/clk?jk=e6e278ed52532f73',
                      'http://ca.indeed.com/rc/clk?jk=a1f14d52c7798d7b',
                      'http://ca.indeed.com/rc/clk?jk=112350d5e020241f',
                      'http://ca.indeed.com/rc/clk?jk=a324c2dcade7dc5c',
                      'http://ca.indeed.com/rc/clk?jk=77895efdf28ad6fa',
                      'http://ca.indeed.com/cmp/BEMAC-Construction-Corp./jobs/Project-Control-Professional-90796e764f064a51?r=1'))

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

    #Server-side search for the choices argument of selectizeInput in ui.R
    updateSelectizeInput(session, 'c', choices = as.character(df$Company), server = TRUE)

    #Create a reactive function to look up the indices correponding to the user's inputs
    index <- reactive({
        ind.j <- if(input$j=='') NULL else grep(input$j,df[,'Job'],ignore.case = T)
        ind.c <- {tmp<-lapply(input$c, function(x) {which(df[,'Company']==x)}); Reduce(union,tmp)}
        ind.l <- if(input$l=='') NULL else grep(input$l,df[,'Location'],ignore.case = T)
        ind.d <- which(df[,'Posted']<=input$d)
        ind.s <- {tmp<-lapply(input$s, function(x) {which(df[,'Source']==x)}); Reduce(union,tmp)}
        ind.all <- list(ind.j,ind.c,ind.l,ind.d,ind.s)
        ind <- if(is.null(ind.s)) NULL else {ind.null<- which(lapply(ind.all,is.null)==TRUE) ;Reduce(intersect,ind.all[-ind.null])}

    })

    #Create a reactive function to return the search results by returning the indices looked up in the index function above
    search <- reactive({

              df[index(),]

    })

    #Print the results of the index function above to test if it works properly
    output$printIndex <- renderUI({
           list(index())
    })

    #Send the searchresult table to ui.R to print the results of the search function above
    output$searchresult <- renderDataTable({
        input$action6   #triggered only when button is pressed
        if(input$action6==0) return() 
        else{isolate({
            transformed <- transform(search(), Link = paste('<a href = ', shQuote(url), '>', 'Click</a>'))
            transformed <- transformed[,c(1:3,5,7,4,6)] #Rearrange columns
            transformed[-7] #Remove last column
        })
        }
    }, option=list(autoWidth=FALSE,pageLength=100,
                   columnDefs = list(list(targets =c(5,6) -1, searchable = FALSE),list(sWidth=c("100px")))))


}

ui <- shinyUI(fluidPage(

    #Display datatable filters on top
    tags$head(tags$style("tfoot {display: table-header-group;}")),        

    #Add a title
    h1('Power Search'),

    #Use the Sidebar layout
    sidebarLayout(
        sidebarPanel(

            #Add various fields for the user in order to search the dataframe  
                     h5('Note: Running the app takes a little while at startup.'),
                     helpText('Job:'),
                     textInput('j',''),
                     helpText('Company:'),
                     selectizeInput('c','',choices=NULL,multiple=T),
                     helpText('Location:'),
                     textInput('l',''),
                     sliderInput('d','Posted (days ago)',min = 0,max = 60,step = 5,value = 60),
                     checkboxGroupInput('s','',choices = c('Indeed','Glassdoor'),selected = c('Indeed','Glassdoor')),
                     actionButton('action6','Search!')
        ),


        mainPanel(

            #Display results
            htmlOutput('printIndex'),
            dataTableOutput('searchresult')
        )      

    )
))

shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r datatable shiny


    【解决方案1】:

    你遇到的问题是 which 函数:

    > which(rep(FALSE, 5))
    integer(0)
    

    你可以改变:

    ind <- if(is.null(ind.s)){
      NULL
    }else{
      ind.null<- which(lapply(ind.all,is.null)==TRUE)
      Reduce(intersect,ind.all[-ind.null])
    }
    

    ind <- if(is.null(ind.s)){
      NULL
    }else{
      Reduce(intersect,ind.all[!sapply(ind.all,is.null)])
    }
    

    【讨论】:

    • 非常感谢约翰!所以我想问题是ind.null = 0 和ind.all[-0] 不起作用的情况。正如您所建议的,解决方法是使用逻辑向量而不是数字向量对ind.all 进行子集化。这是否证实了我的理解?
    • integer(0) 是一个空整数向量,而不是 0L。对空整数向量求反没有效果。使用空整数向量的子集将返回空结果。
    • 作为对这个问题的跟进并参考之前发布的问题here,请尝试取消选中“确实”或尝试任何其他导致 0 行数据框的组合,然后点击搜索和走着瞧吧。有人告诉我这个错误已经在闪亮的开发版本中得到解决,但我在开发版本中尝试过,我仍然得到同样的错误。您能否解释一下可能导致 0 行案例问题的原因?
    • 您的 data.frame 为空。 paste('&lt;a href = ', shQuote(search()$url), '&gt;', 'Click&lt;/a&gt;') 但返回 "&lt;a href = \"\" &gt; Click&lt;/a&gt;"。然后,您尝试将这一新列与一行绑定到没有行的 data.frame。因此出现错误消息。
    • 惊人的观察!我已经被这个应用程序卡住了一段时间,我在几分钟内就解决了我的问题,谢谢你。很多很多的赞赏!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多