簡體   English   中英

將反應性 output 存儲在向量中 - Shiny R

[英]Storing a reactive output in a vector - Shiny R

我正在構建一個 shiny 應用程序。 我使用了一些過濾器並渲染了一個數據框,並且數據框根據用戶輸入動態變化。 但是我無法將數據框中的特定列值存儲到向量中。 我需要將每次反應的 output 存儲到一個向量中,以便以后可以再次使用這些值。 這里的值存儲在 text_vec 中,我需要將其傳遞到 API 但我無法從 text_vec 訪問值,我必須每次將更新后的值傳遞到 API

library(dplyr)
library(shiny)

shinyApp(ui = fluidPage(

  sidebarLayout(

    sidebarPanel(
      selectInput(inputId = "cyl",
                  label = "Number cylinders:",
                  choices = c("all",sort(unique(mtcars$cyl))),
                  selected = "all"),
      actionButton("capture",
                   "capture value")

    ), # closes sidebarPanel


    mainPanel(

      tableOutput("text"),
      tableOutput("text2"),
      tableOutput("text3"),
      tableOutput("table")

    ) # closes mainPanel
  ) # closes sidebarLayout    

), # closes fluidPage

server = function(input, output) {

  # some example reactive data    
  cars_react <- reactive({

    mtcars %>% 
      filter(cyl == input$cyl | input$cyl == "all")

  })

  # simply global assignment of a reactive vector
  observeEvent(cars_react(), {

    # here is a globally assigned vector taken from the reactive data
    # reused in a render statement it will not react to change, since it is not reactive 

    test_vec3 <<- unique(cars_react()$hp)

  })



  # here a file is written to the working directory of your shiny app
  # everytime cars_react() changes write (and overwrite) vector to a file 
  observeEvent(cars_react(), {

    test_vec = unique(cars_react()$hp)

    saveRDS(test_vec, file = "test_vec.Rdata")

  })

  # same as above but the file is gradually growing and not overwritten
  # everytime cars_react() changes add vector to a (over several sessions growing) list
  observeEvent(cars_react(), {

    test_vec2 = unique(cars_react()$hp)

    if (file.exists("test_list.Rdata")) {

      temp = readRDS("test_list.Rdata")

      test_list = c(temp, list(test_vec2))

    } else {

      test_list = list(test_vec2)

    }

    saveRDS(test_list, file = "test_list.Rdata")


  })

  # here we access the reactive data with isolate and make it non-reactive, but can update the values through a button click
  text_vec <<- eventReactive(input$capture, {

    isolate(unique(cars_react()$hp))

  })



  # output of our reactive data as table
  output$table <- renderTable({

    cars_react()

  })   

  # text output of globally assigned non-reactive vector test_vec3 (not changing!)
  output$text <- renderText({

    test_vec3

  })   

  # you can capture values of reactives with isolate, but then, they don't change anymore 
  # text output of isolated formely reactive vector unique(cars_react()$hp (not changing!)
  output$text2 <- renderText({

    isolate(unique(cars_react()$hp))

  })   

  # text output of new reactive vector (changes when input$capture button is clicked)
  output$text3 <- renderText({
    text_vec()

  })  

  for (i in text_vec)
  {
    url = "https://oscar.com/prweb/PRRestService/"
    parameters<-'{
    {
    "Reference":"Account"
    ,"ReferenceValue":""
    }'
      b<-fromJSON(parameters)
      b["ReferenceValue"]=i
      r <- POST(url, body = parameters,encode = "json")
      r_c<-toJSON(content(r))
      print(r_c)
    }


  }


)

讓數據幀在 Shiny 應用程序中使用的所有環境中持久存在的一種簡單方法是使用“<<-”分配而不是“<-”分配。這不是一個很好的編程技術,但它可能是你希望找到什么。

# To get a data frame to persist, use
a <<- b

# instead of
a <- b

**更新答案**

根據您更新的答案,我會將您的 API 調用包裝到一個observeEvent中,一旦按下操作按鈕就會觸發。 由於您沒有提供帶有一些真實代碼的工作示例,因此我不確定下面的示例是否有幫助。 我進一步假設您的for loop是正確的並且可以正常工作(就我而言,如果沒有真正的 API 和一些實際值,我無法知道)。

library(dplyr)
library(shiny)
library(httr)
library(jsonlite)

shinyApp(ui = fluidPage(


      selectInput(inputId = "cyl",
                  label = "Number cylinders:",
                  choices = c("all",sort(unique(mtcars$cyl))),
                  selected = "all"),
      actionButton("capture",
                   "capture value")


), # closes fluidPage

server = function(input, output) {

  # some example reactive data    
  cars_react <- reactive({

    mtcars %>% 
      filter(cyl == input$cyl | input$cyl == "all")

  })



  # here we access the reactive data with isolate and make it non-reactive, but can update the values through a button click
  observeEvent(input$capture, {

    for (i in unique(cars_react()$hp))
    {
      url = "https://oscar.com/prweb/PRRestService/"
      parameters<-'{
      "Reference":"Account"
      ,"ReferenceValue":""
      }'
      b<-fromJSON(parameters)
      b["ReferenceValue"]=i
      r <- POST(url, body = parameters,encode = "json")
      r_c<-toJSON(content(r))
      print(r_c)
    }

  })

}

)

舊答案

從你的問題中不清楚你想如何、在哪里以及多久使用你的反應數據框的向量。 但這是一個重要的問題,因為當您來自純非反應性 R 環境時,很難掌握反應性的概念以及如何訪問它。

下面是一個簡單的示例應用程序,它展示了如何訪問響應式數據幀中的向量,以及如何使用它們。

我希望它有助於更好地理解 shiny 中的反應性。

library(dplyr)
library(shiny)

shinyApp(ui = fluidPage(

  sidebarLayout(

    sidebarPanel(
    selectInput(inputId = "cyl",
                label = "Number cylinders:",
                choices = c("all",sort(unique(mtcars$cyl))),
                selected = "all"),
    actionButton("capture",
                 "capture value")

  ), # closes sidebarPanel


    mainPanel(

      tableOutput("text"),
      tableOutput("text2"),
      tableOutput("text3"),
      tableOutput("table")

  ) # closes mainPanel
  ) # closes sidebarLayout    

), # closes fluidPage

  server = function(input, output) {

# some example reactive data    
cars_react <- reactive({

  mtcars %>% 
    filter(cyl == input$cyl | input$cyl == "all")

  })

# simply global assignment of a reactive vector
observeEvent(cars_react(), {

    # here is a globally assigned vector taken from the reactive data
    # reused in a render statement it will not react to change, since it is not reactive 

    test_vec3 <<- unique(cars_react()$hp)

    })

  # here a file is written to the working directory of your shiny app
  # everytime cars_react() changes write (and overwrite) vector to a file 
  observeEvent(cars_react(), {

    test_vec = unique(cars_react()$hp)

    saveRDS(test_vec, file = "test_vec.Rdata")

    })

  # same as above but the file is gradually growing and not overwritten
  # everytime cars_react() changes add vector to a (over several sessions growing) list
  observeEvent(cars_react(), {

    test_vec2 = unique(cars_react()$hp)

    if (file.exists("test_list.Rdata")) {

      temp = readRDS("test_list.Rdata")

      test_list = c(temp, list(test_vec2))

    } else {

    test_list = list(test_vec2)

    }

    saveRDS(test_list, file = "test_list.Rdata")


  })

  # here we access the reactive data with isolate and make it non-reactive, but can update the values through a button click
  text_vec <- eventReactive(input$capture, {

    isolate(unique(cars_react()$hp))

  })

  # output of our reactive data as table
  output$table <- renderTable({

    cars_react()

    })   

  # text output of globally assigned non-reactive vector test_vec3 (not changing!)
  output$text <- renderText({

    test_vec3

  })   

  # you can capture values of reactives with isolate, but then, they don't change anymore 
  # text output of isolated formely reactive vector unique(cars_react()$hp (not changing!)
  output$text2 <- renderText({

    isolate(unique(cars_react()$hp))

  })   

  # text output of new reactive vector (changes when input$capture button is clicked)
  output$text3 <- renderText({

    text_vec()

  })  

  }

)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM