When working with shiny, uploading data is a bit of a hassle. There are a number of corner cases one has to be mindful of. For example:

  • checking that the uploaded file is of the correct format

  • checking if R can load the file and prevent errors

  • while dealing with excel files, providing an option to choose the sheet number.

  • while using Googlesheets, the hassle of authentication and stuff.

The {datamods} package helps to easily load and use data in shiny apps with the help of modules.
There are 4 modules that can load data from various different sources. The modules with a short intro are described below

Import Modules

Data Source

From environment

Imports data from the user’s global environment or a package environment to retrieve included in it. It searches for data sets in the global environment and lets the user choose the data to use.

# UI
import_globalenv_ui("myid")

# Server
imported <- import_globalenv_server("myid")

From file

Imports data from an external file. The file can be of any format, csv, xlsx, tsv etc.. Import is performed by package rio. In case of Excel files, it gives an option to choose the sheet.

# UI
import_file_ui("myid")

# Server
imported <- import_file_server("myid")

From clipboard

Imports data via copy/paste. Simply copy and paste data from any source.

# UI
import_copypaste_ui("myid")

# Server
imported <- import_copypaste_server("myid")

From Googlesheet

Imports data from a Googlesheet. Use the shareable link to read data.

# UI
import_googlesheets_ui("myid")

# Server
imported <- import_googlesheets_server("myid")

Usage

All modules are used in the same way in a Shiny application, here is an example:

library(shiny)
library(datamods)

ui <- fluidPage(
  tags$h3("Import data with copy & paste"),
  fluidRow(
    column(
      width = 4,
      import_copypaste_ui("myid")
    ),
    column(
      width = 8,
      tags$b("Imported data:"),
      verbatimTextOutput(outputId = "status"),
      verbatimTextOutput(outputId = "data")
    )
  )
)

server <- function(input, output, session) {

  imported <- import_copypaste_server("myid")

  output$status <- renderPrint({
    imported$status()
  })
  output$data <- renderPrint({
    imported$data()
  })

}

shinyApp(ui, server)  

All modules have the same return value server-side, a list with three slots:

  • status: a reactive function returning the status: NULL, error or success.
  • name: a reactive function returning the name of the imported data as character.
  • data: a reactive function returning the imported data.frame.

Update Modules

This module allow to dynamically select, rename and convert variables of a dataset.

Some options for converting to date and numeric are available in a dropdown menu.

Return value of the module is a reactive function with the update data.

Validate

When importing data into an application it can be useful to check that data respect some expectations: number of rows/columns, existence of a variable, … This module allow to validate rules defined with package validate.

# UI
validation_ui("validation", display = "inline")

# Server
results <- validation_server(
  id = "validation",
  data = dataset,
  n_row = ~ . > 20, # more than 20 rows
  n_col = ~ . >= 3, # at least 3 columns
  rules = myrules
)

# Rules are defined as follow:
myrules <- validator(
  is.character(Manufacturer) | is.factor(Manufacturer),
  is.numeric(Price),
  Price > 12, # we should use 0 for testing positivity, but that's for the example
  !is.na(Luggage.room),
  in_range(Cylinders, min = 4, max = 8),
  Man.trans.avail %in% c("Yes", "No")
)
# Add some labels
label(myrules) <- c(
  "Variable Manufacturer must be character",
  "Variable Price must be numeric",
  "Variable Price must be strictly positive",
  "Luggage.room must not contain any missing values",
  "Cylinders must be between 4 and 8",
  "Man.trans.avail must be 'Yes' or 'No'"
)
# you can also add a description()

Validation results can be displayed in a dropdown menu (above left) or inline where the module is called.

The return value server-side is a list with the following items:

  • status: a reactive function returning the best status available between “OK”, “Failed” or “Error”.
  • details: a reactive function returning a list with validation details.

Filter

Interactively filter a data.frame and generate code to reproduce filters applied:

# UI
filter_data_ui("filtering", max_height = "500px")

# Server
res_filter <- filter_data_server(
  id = "filtering",
  data = reactive(mtcars),
  name = reactive("mtcars"),
  vars = reactive(names(mtcars)),
  widget_num = "slider",
  widget_date = "slider",
  label_na = "Missing"
)

You can select variables for which to create a filter and choose widgets used to create the UI filter.

The return value server-side is a list with the following items:

  • filtered: a reactive function returning the data filtered.
  • code: a reactive function returning the dplyr pipeline to filter data.
  • expr: a reactive function returning an expression to filter data.