Working with S4 data structures in Shiny app


#1

Hi guys,

I am hoping that someone will be able to help me to work with input files constructed into an S4 object within a shiny application.

The default behaviour in R is as follows:

library(flowCore)
fs <- read.flowSet(files = ("pathtomultiplefiles.fcs"))

# fs object is a set of files contained in an S4 object - data from individual files can be accessed by "[[" method
fs[[1]]

In the shiny application I have used fileInput for the user to upload files and constructed the reactive expression (called data()) containing the fs object:

ui <- fluidPage(

  titlePanel("Upload .fcs files:"),

  sidebarLayout(
    sidebarPanel(
      fileInput(inputId = "Files",
                label = "Select Samples",
                multiple = TRUE,
                accept = ".fcs")
    ),

    mainPanel(
      textOutput("class"),
      textOutput("names"),
    )
  )
)

server <- function(input, output) {

    data <- reactive({
       fs <- read.flowSet(files = input$Files$datapath)
    })

  output$class <- renderText({
    req(input$Files)
    print(class(data()))
  })

  output$names <- renderText({
    req(input$Files)
    print(sampleNames(data()))  # Print the filenames
  })

}

shinyApp(ui = ui, server = server)

The files have been successfully added as the class and names outputs yield the correct results.

The problem is how do you extract elements from data() (e.g. data()[[1]])? Is this possible or should the data be handled in a different way?

Thanks for your help!


#2

as per the function documentation accessing elements in this way is intended (Q: is flowframe object actually a dataframe of dataframes?) (https://www.rdocumentation.org/packages/flowCore/versions/1.38.2/topics/flowSet-class)

Methods
[, [[
Subsetting. x[i] where i is a scalar, returns a flowSet object, and x[[i]] a flowFrame object. In this respect the semantics are similar to the behavior of the subsetting operators for lists. x[i, j] returns a flowSet for which the parameters of each flowFrame have been subset according to j, x[[i,j]] returns the subset of a single flowFrame for all parameters in j. Similar to data frames, valid values for i and j are logicals, integers and characters. Usage: flowSet[i] flowSet[i,j] flowSet[[i]]
Subsetting by frame name. This will return a single flowFrame object. Note that names may have to be quoted if they are no valid R symbols (e.g. flowSet"sample 1"

An important note from the documentation to be aware of:

... flowSet objects are intended to contain experimental data in the order of hundreds of Megabytes, which can effectively be treated as read-only: typical tasks are the extraction of subsets and the calculation of summary statistics. ...


#3

Thanks for helping!

Essentially a flowSet (fs) consists of multiple flowFrame (fr) objects (representing each of the files). Information from each file can be accessed as follows:

fs <- read.flowSet(files = "pathtomultiplefiles.fcs")
fr <- fs[[1]]   #extracts the first flowFrame object
matrix <- fs[[1]]@description$SPILL  #extracts a matrix from the flowFrame

I have no problem working with these objects in R.

The problem is how to extract this information within the shiny app with files uploaded by the user?

How can I extract a flowFrame from data()? I have tried data(fs[[1]]) and many others with no success...

Are there other ways of handling file uploads other than using reactive expressions?


#4

I have solved the problem!

Arguments to extract data should be specified after the reactive expression:

data <- reactive({
read.flowSet(files = input$Files$datapath)
})

fr <- data()[[1]]

Thanks for your input!