R/Shiny - 如何反复写一个包含actionButton的.csv?

Luk*_*ham 2 csv r shiny

我试图找出如何根据最终用户的选择编写.csv.所做的选择将对"geodata.csv"进行子集化,并在应用程序文件夹中编写单独的"solution.csv"文件.

注意 - 我创建了一个github仓库,以便更轻松地解决问题.它包含geodata.csv,ui.R和server.R但还没有解决方案.

geodata.csv

Postcode,HC,BSL,Position Location
10,1,A,C
10,1,A,D
10,1,A,D
11,1,B,C
11,1,B,C
Run Code Online (Sandbox Code Playgroud)

ui.R

shinyUI(
 pageWithSidebar(
  headerPanel('Min. working example - write a csv based on user input'),

  sidebarPanel(
   selectInput("filter1", "First selection:" 
              , choices = c(Choose='', "A", "B")
              #, multiple=T
              ),

   selectInput("filter2", "Second selection:", 
              choices = c(Choose='', "C", "D")
              ),
   br(),
   p("Include actionButton to prevent write occuring before user finalises selection"),  
   actionButton("generateButton","Write Data")    
  ),
  mainPanel()
 )
)
Run Code Online (Sandbox Code Playgroud)

server.R

# Load data
setwd("/Users/lukesingham/SOtestApp")
geodata <- read.csv("geodata.csv", na.string = "#N/A", row.names=NULL)

# Reactivity to subset data ####
shinyServer(function(input, output) {
  geodatasetInput <- reactive({

    # BSL switch
    selection <-switch(input$BSL
                       , A = "A"
                       , B = "B"
                       ) 
    # Location switch    
    selection2 <-switch(input$Location
                       , C = "C"
                       , D = "D"
                       )

    # subset based on selection
    Subgeodata <- subset(geodata, BSL == selection & Position.Location == selection2)

    # Execute selections on data upon button-press
    input$generateButton

    # aggregate by postcode
    Subgeodata <- Subgeodata[1:2] #no longer need other columns
    AggSubGdata <- aggregate(. ~ Postcode, data=Subgeodata, FUN=sum)
    isolate(write.csv(AggSubGdata
              , file = "/Users/lukesingham/SOtestApp/solution.csv"
              , row.names=F
    ))
  })
})
Run Code Online (Sandbox Code Playgroud)

solution.csv

例如,根据用户选择AD解决方案文件应如下所示:

Postcode,HC
10,2
Run Code Online (Sandbox Code Playgroud)

Mar*_*pov 6

这是工作示例:

# Load data
setwd("/Users/lukesingham/SOtestApp")
geodata <- read.csv("geodata.csv", na.string = "#N/A", row.names=NULL)

# Reactivity to subset data ####
shinyServer(function(input, output) {
  geodatasetInput <- observe({

    # Execute selections on data upon button-press
    if(input$generateButton == 0) return()

    inp.BSL <- isolate(input$filter1)
    inp.loc <- isolate(input$filter2)
    if (inp.BSL=='' | inp.loc=='') return()

    # BSL switch
    selection <-switch(inp.BSL
                       , A = "A"
                       , B = "B"
                       ) 
    # Location switch    
    selection2 <-switch(inp.loc
                       , C = "C"
                       , D = "D"
                       )

    # subset based on selection
    Subgeodata <- subset(geodata, BSL == selection & Position.Location == selection2)

    # browser()
    # aggregate by postcode
    Subgeodata <- Subgeodata[1:2] #no longer need other columns
    AggSubGdata <- aggregate(. ~ Postcode, data=Subgeodata, FUN=sum)
    write.csv(AggSubGdata
              , file = "solution.csv"
              , row.names=F
    )
  })
})
Run Code Online (Sandbox Code Playgroud)

并简要分析您的代码:

  1. geodatasetInput根本没有开始的主要原因是因为它是一个reactive()表达.reactive()只有当它被renderTable()@pops的答案中的其他东西调用时才会被评估.如果你想让它自己执行,它应该是observe().

  2. input$generateButton在observe()表达式的开头可能是个好主意.

  3. ui.R你调用一个数字输入栏filter1,但您试图获取其值分别为input$BSLserver.R; 同样如此filter2.

  4. 由于您只想geodataSetInput触发generateButton,所有其他input$和反应式表达式geodataSetInput都应该与之隔离isolate().另一方面,没有必要隔离,write.csv因为这个特定的函数调用不涉及任何"动态"参数.