Can't read an .RData fileInput
The following example solves the problem. It allows you to upload all .RData
files.
Thanks to @Spacedman for pointing me to a better approach of loading the data:
Load the file into a new environment and get it from there.
For the matter of the example being "standalone" I inserted the top section that stores two vectors to your disk in order to load and plot them later.
library(shiny)
# Define two datasets and store them to disk
x <- rnorm(100)
save(x, file = "x.RData")
rm(x)
y <- rnorm(100, mean = 2)
save(y, file = "y.RData")
rm(y)
# Define UI
ui <- shinyUI(fluidPage(
titlePanel(".RData File Upload Test"),
mainPanel(
fileInput("file", label = ""),
actionButton(inputId="plot","Plot"),
plotOutput("hist"))
)
)
# Define server logic
server <- shinyServer(function(input, output) {
observeEvent(input$plot,{
if ( is.null(input$file)) return(NULL)
inFile <- isolate({input$file })
file <- inFile$datapath
# load the file into new environment and get it from there
e = new.env()
name <- load(file, envir = e)
data <- e[[name]]
# Plot the data
output$hist <- renderPlot({
hist(data)
})
})
})
# Run the application
shinyApp(ui = ui, server = server)
Read and Use Several Objects in an .RData fileInput in Shiny
This code works:
library(shiny)
# Define several objects and store them to disk
x <- rnorm(100)
y <- rnorm(200)
z <- "some text for the title of the plot"
save(x, file = "x.RData")
save(x, y, z, file = "xyz.RData")
rm(x, y, z)
# Define UI
ui <- shinyUI(fluidPage(
titlePanel(".RData File Upload Test"),
mainPanel(
fileInput("file", label = ""),
actionButton(inputId="plot","Plot"),
tableOutput("contents"),
plotOutput("hist"))
)
)
# Define server logic
server <- shinyServer(function(input, output) {
observeEvent(input$plot,{
if ( is.null(input$file)) return(NULL)
inFile <- isolate({input$file })
file <- inFile$datapath
load(file, envir = .GlobalEnv)
# Plot the data
output$hist <- renderPlot({
plot(x,y[1:100],main=z)
})
})
})
# Run the application
shinyApp(ui = ui, server = server)
Produces the plot like:
Loading User input .Rdata on Shiny App
What if you try to use the new.env
function and load the .Rdata in to a new environment.
library(shiny)
server <- function(input, output) {
# Global variable to store loaded environment
env <<- NULL
load_Rdata <- function(){
if(is.null(input$file)) return(NULL)
inFile <- isolate({ input$file })
# Create new environment to load data into
n.env <- new.env()
env <<- n.env
load(inFile$datapath, envir=n.env)
# Check if specified variable exists in environment
if( !is.null(n.env$var) ){
output$out <- renderPrint({ str(n.env$var) })
}
else{
output$out <- renderPrint({ "No variable var in .Rdata file" })
}
}
save_Rdata <- function(){
if ( !is.null(env) ){
env$new.var <- "My new variable"
save(env, file="~/savedWorkspace.Rdata")
}
else{
output$out <- renderPrint({ "No .Rdata file loaded" })
}
}
observeEvent(input$btnLoad,{
load_Rdata()
})
observeEvent(input$btnSave,{
save_Rdata()
})
}
ui <- shinyUI(fluidPage(
fileInput("file", label = "Rdata"),
actionButton(inputId="btnLoad","Load"),
actionButton(inputId="btnSave","Save"),
verbatimTextOutput("out")
))
shinyApp(ui = ui, server = server)
The saved variable can be accessed through:
> load("~/savedWorkspace.Rdata")
> env$new.var
[1] "My new variable"
And a example workspace to load can be created as:
> var <- "My variable to load"
> save.image(file="~/myWorkspace.Rdata")
Was it something like this you were looking for?
Shiny: Dynamically load .RData file
I think you just need to move the load
statement outside of the renderTable
function. So you should have
load(paste0(input$one,"/",input$two,".RData"))
output$table1 <- renderTable({myData})
If you look at the help file for renderTable
, the first argument is
expr: An expression that returns an R object that can be used with
xtable.
load
does not return this.
error running shiny app can not open connection
As Vishesh says, I think you might be needing to use readRDS
instead of load
, but here's a shiny
app that allows all three: csv, rds, or rda.
First, quick debugging setup so we have three types of files to test with:
write.csv(mtcars, file="mt.csv")
saveRDS(mtcars, file="mt.rds")
save(mtcars, file="mt.rda")
(Certainly not needed for a production app.)
Now the app:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Choose CSV, rda, or rds File"),
tags$hr(),
checkboxInput("header", "Header (if CSV)", TRUE),
uiOutput("rda_objname")
),
mainPanel(
tableOutput("contents")
)
)
)
server <- function(input, output) {
file1_ <- reactive({
req(input$file1)
# might also work with input$file1$type, which is something like
# 'application/vnd.ms-excel', though for me in testing this was
# blank for RDS/RDA ...
a <- input$file1
a$ext <- tolower(tools::file_ext(input$file1$name))
# ... though length==1 since we did not do multiple = TRUE
a$ext <- ifelse(a$ext == "rdata", "rda", a$ext)
a
})
rawdat <- reactive({
req(file1_())
inFile <- file1_()
# if we ever do fileInput(..., multiple = TRUE), this will need to
# be on a vector of length > 1
if ("csv" == inFile$ext) {
return( read.csv(inFile$datapath, header = input$header) )
} else if ("rds" == inFile$ext) {
return( readRDS(inFile$datapath) )
} else if (inFile$ext == "rda") {
e <- new.env(parent = emptyenv())
load(inFile$datapath, envir = e)
return( e )
} else return( NULL )
})
output$rda_objname <- renderUI({
# this only displays a select-input if the input file is valid and
# an Rdata-looking file, otherwise the select-input is absent
req(file1_())
inFile <- file1_()
if (inFile$ext == "rda") {
obj <- isolate(ls(envir = rawdat()))
selectInput("objname", "RDA object name",
choices = c("Select object name ...", obj))
} else return( NULL )
})
dat <- reactive({
req(rawdat())
inFile <- isolate(file1_())
if (inFile$ext == "rda") {
req(input$objname, input$objname %in% ls(envir = rawdat()))
return( get(input$objname, envir = rawdat()) )
} else return( rawdat() )
})
output$contents <- renderTable({
req(dat())
dat()
})
}
shinyApp(ui, server)
If you select a CSV or RDS file in the fileInput
, then it will automatically render the table. If it ends in .rda
or .rdata
(case-insensitive), then it will create a selector to choose which object within the rda file (since they really store environments with named objects, not a single object).
Demo: with CSV or RDS:
With an RDA file (that has a single object in it, mtcars
:
Some other changes from your code:
- instead of using
if (is.null(...))
, I'm using the moreshiny
-esquereq(...)
methodology; it's a little more user-friendly when things don't go as you (the dev) intended; - I've intentionally
isolate
d a few things that might stand to not be isolated, but I wanted a clear path of reactivity; it is possible if A depends on B and C depends on both A and B that, when A updates, C will update, then B will update, causing C to update again ... dizzying, perhaps, but a consequence of multiple dependency paths. - Because this accepts both types of storage (one object and multi), I need a two-step to retrieve the data:
rawdat()
might be an environment (RDA) or an actual objecvt;dat()
will always be an object orNULL
(if RDA and an object name is not selected). - I don't need the
else return(NULL)
inoutput$rda_objname
, I just have it there for clarity and explicit code in this example; I likely would not have it in my production code. - I also use
return
a lot here; technically, it is not required in any of these uses, again I'm just being explicit for this example.
Loading .RData files into Python
People ask this sort of thing on the R-help and R-dev list and the usual answer is that the code is the documentation for the .RData
file format. So any other implementation in any other language is hard++.
I think the only reasonable way is to install RPy2 and use R's load
function from that, converting to appropriate python objects as you go. The .RData
file can contain structured objects as well as plain tables so watch out.
Linky: http://rpy.sourceforge.net/rpy2/doc-2.4/html/
Quicky:
>>> import rpy2.robjects as robjects
>>> robjects.r['load'](".RData")
objects are now loaded into the R workspace.
>>> robjects.r['y']
<FloatVector - Python:0x24c6560 / R:0xf1f0e0>
[0.763684, 0.086314, 0.617097, ..., 0.443631, 0.281865, 0.839317]
That's a simple scalar, d is a data frame, I can subset to get columns:
>>> robjects.r['d'][0]
<IntVector - Python:0x24c9248 / R:0xbbc6c0>
[ 1, 2, 3, ..., 8, 9, 10]
>>> robjects.r['d'][1]
<FloatVector - Python:0x24c93b0 / R:0xf1f230>
[0.975648, 0.597036, 0.254840, ..., 0.891975, 0.824879, 0.870136]
Related Topics
1-Dimensional Matrix Is Changed to a Vector in R
Extract Last Non-Missing Value in Row with Data.Table
Repeat the Re-Sampling Function for 1000 Times? Using Lapply
R Ggplot Ordering Bars in "Barplot-Like " Plot
Why Does Mapply Not Return Date-Objects
R Group By, Counting Non-Na Values
In R, How to Plot into a Memory Buffer Instead of a File
Fastest Way to Sort Each Row of a Large Matrix in R
Are Data Tables with More Than 2^31 Rows Supported in R with the Data Table Package Yet
3D Equivalent of the Curve Function in R
Change the Order of Stacked Fill Columns in Ggplot2
Find Most Frequent Combination of Values in a Data.Frame