【问题标题】:Pass a reactiveValues dataframe to a reactive expression将 reactiveValues 数据框传递给反应式表达式
【发布时间】:2019-09-11 20:46:23
【问题描述】:

我有一个简单的闪亮应用程序,其中我将数据帧存储在reactiveValues() 中,然后过滤date 以将其传递给reactive() 表达式。但我没有得到任何结果。请注意,此reactiveValues() 数据帧稍后将在多个其他反应表达式中进行子集化,并且这些表达式将被组合以获得最终结果,因此它只需要在反应值中通过date 进行过滤。这个answer 是我使用它的原因

    #ui.r
        shinyUI(
      fluidPage(
        titlePanel("Organizational Analysis"),
        sidebarLayout(

          sidebarPanel(
            selectInput("gr", "Group by:",
                        choices = c("val","Gender")
            ),
            sliderInput("Date Range",
                        "Dates:",
                        min = as.Date("2018-04-21","%Y-%m-%d"),
                        max = as.Date("2018-10-27","%Y-%m-%d"),
                        value=as.Date("2018-10-27"),
                        timeFormat="%Y-%m-%d")

          ),

          mainPanel(
           visNetworkOutput("network")
          )
        )

      )
    )

    #server.r
    library(shiny)
    library(visNetwork)
    library(geomnet)
    library(igraph)
    library(dplyr)

    shinyServer(function(input, output) {


actors <- data.frame(name1=c("Alice", "Bob", "Cecil", "David",
                               "Esmeralda"),
                       name2=c("Ali", "Boby", "Cecilia", "Daviddff",
                               "Esmeraldagj"),
                       date=c("2018-10-27","2018-09-27","2018-10-17","2018-07-27","2018-04-21"),
                       val<-c(10,20,10,20,10))

  sampler<-reactiveValues(sampl=actors) 
  observe({
    s<-sampler$sampl %>% dplyr::filter( date>= input$DateRange[1] & date <= 
    input$DateRange[2])
    s
  })
      actors2<-reactive({
        actors<- actors %>% dplyr::filter( date>= input$Dates[1] & date<= input$Dates[2])
        actors

      })
      nodes2<-reactive({
        eids<-as.character(actors2()$name1)
        mids<-as.character(actors2()$name2)
        nodes<-data.frame(c(eids,mids))
        nodes<-unique(nodes)
        nodes$ID <- seq.int(nrow(nodes))
        colnames(nodes)<-c("label", "id")
        nodes<-nodes[,c(2,1)]
        colnames(actors2())[1]<-"id"
        nodes$id<-nodes$label
        nodes<-merge(x = actors2(), y = nodes, by = "id", all = TRUE)
        nodes$label<-nodes$id
        nodes [is.na(nodes)] <- "Unknown"
        nodes<-nodes[,c(1,5,4)]
        if(input$gr=="val"){
          nodes$color<-""

          for(i in 1:nrow(nodes)){
            if(nodes[i,3]==10){
              nodes[i,4]<-"green"
            }
            else if(nodes[i,3]==20){
              nodes[i,4]<-"orange"
            }
            else if(nodes[i,3]=="Unknown"){
              nodes[i,4]<-"red"
            }

          }
        }
        else if(input$gr=="Gender"){

        }
        nodes
      })


      #Edges
      edges2<-reactive({
        edges <- actors2()[,1:2]
        colnames(edges) <- c("from", "to") 
        edges
      })


      output$network<-renderVisNetwork(
        visNetwork(nodes2(), edges2(), width = "100%") %>%
          visIgraphLayout() %>%
          visNodes(
            shape = "dot",
            shadow = list(enabled = TRUE, size = 10)
          ) %>%
          visEdges(
            shadow = FALSE,
            color = list(color = "#0085AF", highlight = "#C62F4B")
          ) %>%
          visOptions(highlightNearest = list(enabled = T, degree = 1, hover = T),
                     nodesIdSelection = TRUE) %>% 
          visLayout(randomSeed = 11)


      )


    })

【问题讨论】:

  • 我不认为sampler 下面的observe() 内的代码在做任何事情。它有什么用?
  • 是的,只是为了展示我的方法。如果你可以让它与你的没有问题
  • 我观察了您的代码,我认为我和 Yifu 的回答中有足够的提示让您尝试改进代码。不是粗鲁,只是我不想浏览所有这些代码。干杯!

标签: r shiny


【解决方案1】:

你犯了两个错误:

  1. 您没有将actors 表中的date 列转换为日期格式。只是character
  2. 以下代码未将s 分配给sampler,我创建了另一个反应值n 以使用n(s) 存储此结果
 observe({
    s<-sampler$sampl %>% dplyr::filter( date>= input$DateRange[1] & date <= input$DateRange[2])
    s
  })

为您修复了服务器代码:

server <- function(input, output) {
  actors <- data.frame(name1=c("Alice", "Bob", "Cecil", "David",
                               "Esmeralda"),
                       name2=c("Ali", "Boby", "Cecilia", "Daviddff",
                               "Esmeraldagj"),
                       date=lubridate::ymd(c("2018-10-27","2018-09-27","2018-10-17","2018-07-27","2018-04-21")), # convert character to date
                       val<-c(10,20,10,20,10))

  sampler<-reactiveValues(sampl=actors) 
  n <- reactiveVal() # create this value to store s in observe() below
  observe({
    s<-sampler$sampl %>% dplyr::filter( date>= input$DateRange[1] & date <= input$DateRange[2])
    n(s)
  })

  #n<-reactive({
  #  s()
  #})

  output$tab<-DT::renderDataTable({
    n()
  })
}

shinyApp(ui = ui, server = server)

【讨论】:

  • 我认为这里不需要reactiveValues() 和相关代码。如果您同意,那么您可以使用我的方法,我将删除我的答案(因为您的答案更全面。还建议您从答案中删除 ui 部分,因为那里没有更改(?)并且答案将是更简洁。干杯!
  • 感谢您的回答,但我想稍后对此数据帧进行子集化,并且我知道如果将其存储在 reactiveValues 而不是基于 stackoverflow.com/questions/49313629/… 的反应式中,则可以实现这一点。该表只是为了检查数据集是否已创建。如果您的答案可以做到这一点,那就可以了
  • 嗨@Shree,感谢您的建议。我同意您的版本更简单,这也是我编写代码的方式。但正如 Firmo 所解释的,反应值可能会在其他地方使用。所以我尽量不要修改太多的原始代码。
  • 这个 reactiveValues 数据框稍后将在多个其他响应式表达式中进行子集化,并且这些表达式将被组合以获得最终结果,因此它只需要在 reactiveValues 中按日期过滤
  • 为了让我的目标更清晰,我已经放了几乎所有的实际代码
【解决方案2】:

这是您可能需要的简化版本。确保整个代码中的日期格式正确。 -

shinyServer(function(input, output) {
  actors <- data.frame(name1=c("Alice", "Bob", "Cecil", "David",
                               "Esmeralda"),
                       name2=c("Ali", "Boby", "Cecilia", "Daviddff",
                               "Esmeraldagj"),
                       date=c("2018-10-27","2018-09-27","2018-10-17",
                              "2018-07-27","2018-04-21"),
                       val<-c(10,20,10,20,10))

  sampler <- reactive({
    temp <- actors %>% 
      dplyr::filter(date >= input$DateRange[1] & date <= input$DateRange[2])
    validate(need(nrow(temp) > 0), "No data for selected dates")
  })

  reactive2 <- reactive({
   # sampler() %>% more code
  })

  reactive3 <- reactive({
   # sampler() %>% more code
  })      

  output$tab <- DT::renderDataTable({
    sampler()
  })
})

【讨论】:

  • 感谢您的回答,但我想稍后对此数据帧进行子集化,并且我知道如果将其存储在 reactiveValues 而不是基于 stackoverflow.com/questions/49313629/… 的反应式中,则可以实现这一点。该表只是为了检查数据集是否已创建。
  • @firmo23 您可以在 sampler() 本身中应用该附加过滤器。只需在日期过滤器后包含validate() 条件。查看更新的答案。
  • 这个 reactiveValues 数据框稍后将在多个其他响应式表达式中进行子集化,并且这些表达式将被组合以获得最终结果,因此它只需要在 reactiveValues 中按日期过滤
  • @firmo23 在这种情况下,您可以简单地将sampler() 传递给其他反应者。请参阅更新的答案。我认为这里不需要reactiveValues() + observe() 方法。我的代码实现了同样的效果,但更简洁。
  • 好的,我几乎拥有我拥有的实际代码,我想看看你在这方面的方法
猜你喜欢
  • 2010-11-14
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
  • 2014-02-17
  • 2014-09-20
相关资源
最近更新 更多