fileInput: How to create a dataframe from a .xlsx file within shiny? - r

I am very new to shiny and ran quite fast in a problem which impedes to continue my work. I created a .xlsx file and tried to load this within shiny.
A similar problem was dicussed here but was not finally solved.
I tried to keep the code as simple as possible:
library(shiny)
ui <- fluidPage(
fileInput("uploadFile", "XLSX file"),
verbatimTextOutput("summary")
)
server <- function(input, output) ({
dataset<-reactive({
inFile <- input$uploadFile
dat<-read.xlsx("inFile$datapath", 1)
return(dat)
})
output$summary <- renderText({summary(dataset())})
})
Just loading the .xlsx file in R works fine with this code:
read.xlsx("testdata.xlsx", 1)
Adding browser() after inFile <- input$uploadFile in serverand calling inFile gives I think the correct object which contains .$datapath.
The error I get after uploading the file is:
Error in loadWorkbook(file) : Cannot find inFile$datapath
I hope this is not to silly but I just can figure out how to solve it. What I would like to know is how can I store my uploaded file as a dataframe within shiny?

You should leave the "" from the dat<-read.xlsx("inFile$datapath", 1) line.
This one works:
dat<-read.xlsx(inFile$datapath, 1)
Best,
RĂ³bert

Related

Shiny - How to test fileInput()

I'm trying to write tests in order to check if a shiny function fileInput() is reading files correctly.
My problem is that I don't know what to write in session$setInputs() in order to grab the file from my system.
Here is an example app:
library(shiny)
ui <- fluidPage(
tagList(
fileInput("file", "Please upload a file"),
tableOutput("text")
)
)
server <- function(input, output, session){
file <- reactive({input$file})
output$text <- renderTable({
req(file())
read.csv(file()$datapath)
})
}
shinyApp(ui, server)
Now, I want to be able to use testServer() in order to set a file address and see if my app loads it correctly, but I can't figure out how to do it:
address <- "path/to/text.csv"
testServer(server, {
session$setInputs(file = address)
print(file())
})
I think it has to do with the fact that fileInput() uploads the file to a temp folder and returns to shiny a dataframe where you can get the datapath, but I'm unable to simulate this pass in order to make the test work
I have the same question as you do, I did some investigating and could not find any way of testing fileInput with testServer or testthat. The best solution that I found was testing fileInput by taking a snapshot when recording a test with recordTest() of the shinytest package.
Sorry for answering this late.
I asked the same question at rstudio's forums and got an answer here
The basics of it are setting the file's datapath as a list:
address <- "path/to/text.csv"
testServer(server, { session$setInputs(file= list(datapath = address)) })

R Shiny: View the logfile and update it with new entries

I am new to R and certainly very new to RShiny.
I wrote a packages which logs events into a log file. Rstudio is capable of viewing live logging unitl the file is 5MB. So now i am thinking about writing a Rshiny app that views the logs as they are being written to the file.
Which functions would help me to update the viewer?
Thanks!
You can call invalidateLater inside a reactive when you import the data. Data will be refreshed every time invalidateLater will fire (in my case every second).
Here a really silly example (my .csv doesn't update, it just prints that data is being refreshed to console):
library(shiny)
ui <- fluidPage(
tableOutput("data")
)
server <- function(input, output, session) {
# mtcars.csv will be read every second
mtcars_df <- reactive({
invalidateLater(1000, session)
read.csv("mtcars.csv")
})
# mtcars_df is a reactive, hence will force the table to re-render
output$data <- renderTable({
print(paste("Table refreshed at", Sys.time(), collapse = " "))
mtcars_df()
})
}
shinyApp(ui, server)

Shiny reactive UI not running server code

I'm trying to get a Shiny reactive UI running. It is getting quite complex (in terms of lines of code) so I thought refactoring was a good idea. To put it short, this is my server code:
require(ggplot2)
require(h2o)
shinyServer(function(input, output, session) {
#stop()
localH2o <<- h2o.init(nthreads = 3) #Global variable
source("BuilderServer.R", local = TRUE)[1]
source("ReviewerServer.R", local = TRUE)[1]
# CleanupFUnctions
session$onSessionEnded(function() {
rm(list=ls())
})
})
where I assumed source with local = TRUE was just like copy-paste the content of the R files. So they contain functions of the form output$functionName <- renderUI({code}). The ui code depends on these functions, most of them are reactive, the ui code looks like this:
shinyUI(navbarPage("Metamodel",
tabPanel("Build Custom Model",
fluidRow(
column(12,align="center",
uiOutput("BuilderUpTitle")
)
),
fluidRow(
column(3,
uiOutput("BuilderAxisSelector")
)
)
)
))
In this particular case, the "BuilderUpTitle" function looks like this:
output$BuilderUpTitle <- renderUI({
inFile <- input$BuilderInputFile
if(is.null(input$BuilderInputFile)){
fileInput("BuilderInputFile", "Upload a xlsx file")
} else {
#R Stuff done here with the file
textInput("text", label = h3("Model Title"), value = "Enter text...")
}
})
I wrote the code yesterday and it was working. Today I turned on the computer again, and when launching the app, not even the dependencies from the server.R appear to load (ggplot2 and h2o). The download button from the "BuilderUpTitle" function doesn't appear at all and shiny appears to only execute the ui.R code. I set the workspace to the folder of the sourcefiles and it doesn't help. Even if I uncomment the stop() function from the server, nothing seems to change. Setting breakpoints in RStudio doesn't stop the code inside the server, so that is why I think shiny is not calling the server function. However, the code was working before and I did not modify a single file. I even copied the content of the source files to the server.R code and still they do not load. Is there something obvious that I'm missing? Thank you in advance!
Ok, once again, I found myself what the problem is, and none of the things I said would've made anyone find what was wrong. Here is the tiniest possible code that reproduces the problem:
ui.R
shinyUI(fluidPage(
fluidRow(
uiOutput("itWillLock"),
uiOutput("itWillLock")
)
))
server.R
shinyServer(function(input, output) {
output$itWillLock <- renderUI({
sliderInput("slider","Slider",min=0,max=1,value=0)
})
})
I guess R gets stuck in an infinite loop and never reaches the server.R file. Is this a bug that I should report? Or just common sense will keep people out of this trouble. Thank you!

Does R shiny allow to parse an XML file?

I parse an uploaded XML file in the renderPlot function of the server.R script of R-Shiny
output$oscar <- renderPlot({
doc <- xmlParse("www/Human_body_front_and_side.svg.eps.xml")
#load the XML as a picture
body<-readPicture(saveXML(doc))
#plot it
grid.arrange(pictureGrob(body), ncol=1)
})
but I get the following error for the parsing:
XML content does not seem to be XML
I had loaded the correct libraries (shiny, XML), and checked that the uploaded xml file is fine.
The interesting point is that if, before starting the "runApp" of R-Shiny, I do in the R terminal:
doc <<- xmlParse("Human_body_front_and_side.svg.eps.xml")
no error and everything works fine. So it looks like R shiny has an issue with parsing xml. I am a newbie in R-Shiny, hence does anyone see what it needs to recognize that XML file?
ui.R:
library(shiny)
shinyUI(fluidPage(
titlePanel("Human body"),
sidebarLayout(
sidebarPanel(
),
mainPanel(
plotOutput("humanBody")
)
)
))
server.R
library(shiny)
library(XML)
library(grImport)
library(gridExtra)
# Define server logic to draw a histogram
shinyServer(function(input, output){
output$humanBody <- renderPlot({
doc <- readPicture("./www/Human_body_front_and_side.svg.eps.xml")
grid.arrange(pictureGrob(doc), ncol=1)
})
})
If the goal is to plot the human body from the xml, this code works. Parsing the xml is not necessary since since the readPicture() function expects an XML which your file already is. Let me know if this helps.

Access dataframe in .Rdata from Shiny

I have a small shiny program below which reads in an .Rdata file using Shiny. The code below works as expected, but there is behavior that I desire that I cannot quite figure out how to implement from within Shiny.
To frame the first problem, suppose I have a file called tmp.Rdata and when that .Rdata is loaded into the R workspace it contains a data frame called "foo". My objective is to load the .Rdata using shiny and then access the data frame within it (foo) and do R things to it.
For example, if I was working within R proper, my actions would be something like:
> load('tmp.Rdata')
> str(foo)
And supposing foo is a data frame with K columns, the result of str(foo) would show the typical behavior of str() on the object.
When implementing the code below, the Shiny program runs and I can see the .Rdata loads successfully and that "foo" is in the workspace. However, the resulting action from str() in this instance is to show that the object foo is in the workspace, not the structure of the object foo itself, which is the behavior I want to implement.
chr "foo"
Now, if I know ahead of time that the .Rdata will always have in it a frame called "foo" I could hard code this into the server.R code and all is well. But, the more challenging problem is that my users will save an .Rdata file that contains within it a data frame with an unknown name.
I have searched SO and found similar questions, but not exactly tackling the same problem as far as I can tell, such as the one at the link below
Loading User input .Rdata on Shiny App
Thank you for any suggestions.
ui.R
shinyUI(fluidPage(
titlePanel("Uploading Files"),
sidebarLayout(
sidebarPanel(
h4("Uploading Files"),
fileInput('f1', 'Choose RData File', accept=c('.RData, .Rds'))
),
mainPanel(
h4("Data Structure"),
verbatimTextOutput("datastr")
)
)
))
server.R
shinyServer(function(input, output) {
dataInput <- reactive({
sessionEnvir <- sys.frame()
if (!is.null(input$f1)) load(input$f1$datapath, sessionEnvir)
})
output$datastr <- renderPrint({
ff <- dataInput()
if (is.null(dataInput())) return() else str(ff)
})
})
You could use eval() and parse(). The updated server.R code below shows how:
shinyServer(function(input, output) {
dataInput <- reactive({
sessionEnvir <- sys.frame()
if (!is.null(input$f1)) eval(parse(text = load(input$f1$datapath, sessionEnvir)))
})
output$datastr <- renderPrint({
ff <- dataInput()
if (is.null(dataInput())) return() else str(ff)
})
})
This will only work for RData files. Your ui.R appears to show a desire to accept Rds files too. You'll need to load them with readRDS. The good news is that readRDS will work just fine without eval() and parse(). Perhaps you could add radio buttons to the UI for the user to choose the file type.

Resources