Hi,
Although the question seems easy it required quite some Shiny tricks to get the desired result.
Here is the app I made (read comments how to generate sample data)
library(shiny)
library(DT)
ui <- fluidPage(
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Select a file ----
fileInput("file1", "Choose CSV File",
multiple = FALSE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")),
selectInput("variable", "Choose variable", choices = ""),
selectInput("subset", "Choose subset", choices = ""),
numericInput("nSamples", "How many random samples?", value = 1),
# Button
actionButton("update", "Generate",
class = "btn-primary",style='padding:4px; font-size:120%'),
downloadLink("downloadData", "Download")
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Data file ----
DTOutput("contents")
)
)
)
server <- function(input, output, session) {
#Uncomment, Run and delete these two commented lines of code to get sample file to test...
# df = data.frame(ID = 1:10, zip = c(rep(68503, 5), rep(45763, 5)))
# write.csv(df, "testData.csv", row.names = F)
df = reactiveVal()
randomSubset = reactiveVal()
#Change the variables based on the columns in the file
observeEvent(input$file1, {
df(read.csv(input$file1$datapath))
updateSelectInput(session, "variable", choices = colnames(df()))
})
#For the selected variable, display all different options
observeEvent(input$variable, {
updateSelectInput(session, "subset", choices = unique(df()[,input$variable]))
})
#On update, pick n samples from the selected sub category
observeEvent(input$update, {
randomSubset(df()[eval(parse(text = paste("df()$",input$variable, "==", input$subset, sep = ""))),])
randomSubset(randomSubset()[sample(1:nrow(randomSubset()), input$nSamples), ])
output$contents <- renderDT({
randomSubset()
})
})
#Download csv when completed
output$downloadData <- downloadHandler(
filename = function() {
paste("randomSample.csv", sep="")
},
content = function(file) {
write.csv(randomSubset(), file, row.names = F)
}
)
}
shinyApp(ui, server)
It should work, but beware I did NOT implement any error handling, meaning that if a user uploads a wrong file or tries to pick too many random samples from a dataset that doesn't have them, the app will crash.
Lemme know what you think...
PJ