I'm in the process of creating a Shiny screening application, which would allow users to type R commands like filter
and mutate
on a predetermined dataframe.
Personally, I think the most user friendly way to do this would be to have a blank dataframe column containing screening parameters, where users could input commands like filter(mpg >= 21)
or mutate(cyl_sq = cyl^2)
using the mtcars
dataset as an example.
Simple application to show the intended functionality:
library(shiny)
library(shinydashboard)
library(DT)
library(dplyr)
# Header ------------------------------------------------
header <- dashboardHeader(title = "Example Screening")
# Sidebar ------------------------------------------------
sidebar <- dashboardSidebar()
# Body ------------------------------------------------
body <-
dashboardBody(
fluidRow(
column(6,h3("Screening Parameters")),
column(6,h3("Filtered/Modified Results"))),
fluidRow(
column(6,DT::dataTableOutput("screening_params")),
column(6,DT::dataTableOutput("filtered_results")))
)
# APP ------------------------------------------------
shinyApp(ui <- dashboardPage(
header,
sidebar,
body
),
# Server ----------------------------------------------------------
shinyServer(function(input,output){
output$screening_params <- renderDataTable({
tibble(params = c("filter(mpg >= 21)",
"mutate(cyl_sq = cyl^2)",
rep_len(NA_character_,8))) %>%
DT::datatable(rownames = F,
editable = T)
})
output$filtered_results <- renderDataTable({
mtcars %>%
# input$screening_params
DT::datatable()
})
}))
I would be open to using either the DT
or rhandsontable
or any alternative that someone can think of. Unfortunately it doesn't look like you can grab the edited table values in DT
, but hopefully it provides a good example of what I am after.
I have tried every combination of quosures and mapping functions that I can think of to no avail.
Anyone have any ideas?
This is a slightly different approach, but maybe you'll find it useful. I'm using sqldf
as an SQL query engine, and users can manipulate the data using ad-hoc SQL queries on the given dataset. If this isn't what you're after, I at least hope it will give you some hints on how to do it with dplyr
syntax.
If you still go for the dplyr
option and you have a string with the requested manipulation, you can use the reactive method getDataset
to evaluate the expression you received from the user, manipulate your dataset. Then call getDataset
in the renderDataTable
method, like I did in the attached code.
Example for evaluating a string expression:
eval(parse(text="res <- mtcars %>% filter(mpg < 20)"))
For the SQL option:
library(shiny)
library(shinydashboard)
library(DT)
library(dplyr)
library(sqldf)
# Header ------------------------------------------------
header <- dashboardHeader(title = "Example Screening")
# Sidebar ------------------------------------------------
sidebar <- dashboardSidebar(collapsed = TRUE)
# Body ------------------------------------------------
body <-
dashboardBody(
fluidRow(
#column(6,h3("Screening Parameters")),
column(6,h3("Filtered/Modified Results"))),
fluidRow(
textInput("sql","SQL Query",value = "SELECT * FROM dataset"),
DT::dataTableOutput(("filtered_results"))
)
)
# APP ------------------------------------------------
shinyApp(ui <- dashboardPage(
header,
sidebar,
body
),
# Server ----------------------------------------------------------
shinyServer(function(input,output){
## A new function to load data and perform the SQL query on it
getDataset <- reactive({
query <- input$sql
dataset <- mtcars
sqldf::sqldf(query)
})
output$filtered_results <- renderDataTable({
getDataset() %>%
DT::datatable()
})
}))