I am new to R language. I am trying to run the Tesseract OCR function if the uploaded file is pdf file, it seems like it always goes to the else part. I know there is an error in the if part but I have no clue to use what symbol.
Here are some part of the code
output$table <- renderTable({
if(is.null(input$file)) {return()}
read.table(file=input$file$datapath[input$file$name==input$Select], fill = TRUE, skipNul = TRUE)
# PDF file
if (input$file$datapath[input$file$name==input$Select] == "pdf"){
pdffile <- pdftools::pdf_convert(input$file$datapath[input$file$name==input$Select], dpi = 600)
text <- tesseract::ocr(pdffile)
}
# JPEG file
else{
eng <- tesseract("eng")
text <- tesseract::ocr(input$file$datapath[input$file$name==input$Select], engine = eng)
}
})
Related
I'm creating an application to track soccer statistics for a high school team. The coach wants it to be like an excel sheet, where player data can be inputted and saved to be looked at later. I've figured out how to do that with rhandsontable, but I can't get it to download to my shadow document from my r shiny. I was able to get the shadow doc to work before adding the rhandsontable, but it is no longer working. I'm attaching the code from the server that I'm using to create the table. The player_names is a csv with columns for player name, team level, goals scored,.... other stats. I'm first looking at only one team level (ie varsity), then making the table. It works great in the shiny, but I don't how to save it from there.
output$hot <- renderRHandsontable({
player_names %>%
filter(Team == input$team_level) %>%
rhandsontable()
})
values <- reactiveValues(data = NULL)
observe({
values$data <- hot_to_r(input$hot)
})
# 3. I assign this df to a variable call df1
df1 <- reactive({
values$data
})
Code to make shadow doc:
output$downloadReport <- downloadHandler(
filename = function() {
paste("ophs_soccer", sep = ".", switch(
input$format, PDF = "pdf", HTML = "html", Word = "docx"
))
},
content = function(file) {
src <- normalizePath("shadow_page.Rmd")
# temporarily switch to the temp dir, in case you do not have write
# permission to the current working directory
owd <- setwd(tempdir())
on.exit(setwd(owd))
file.copy(src, "shadow_page.Rmd", overwrite = TRUE)
library(rmarkdown)
out <- render("shadow_page.Rmd", switch(
input$format,
PDF = pdf_document(), HTML = html_document(), Word = word_document()
))
file.rename(out, file)
I tried to create output in the shadow doc like I did with the other reactive inputs, and it did not work. I get an error when trying to download the document.
I have simplified a lot the shiny app I'm trying to build, but, in the idea, I have two functions :
choose_input <- function(n1,n2,n3){
x1 <<- n1+n2
x2 <<- n2+n3
x3 <<- (n1*n2)/n3
}
createmydata <- function(n){
c1 <- c(1:n)
c2 <- c1+(x2*x3)
c3 <- c2+x1
df <- data.frame("column1"=c1,"column2"=c2,"column3"=c3)
return(df)
}
You'll tell me that I can do simply one function with these two because they are very simple, but in my app there are a lot of lines and I have to separate the two. Anyway, here is my simulated code :
ui <- fluidPage(
numericInput("n1",label="Choose the first parameter",min=0,max=100,value=3),
numericInput("n2",label="Choose the second parameter",min=0,max=100,value=4),
numericInput("n3",label="Choose the third parameter",min=0,max=100,value=5),
numericInput("n",label="Choose dataframe length",min=1,max=10000,value=100),
radioButtons("filetype", "File type:",
choices = c("csv", "tsv")),
downloadButton('downloadData', 'Download'),
tableOutput("data")
)
server <- function(input,output){
RE <- reactive({
choose_input(input$n1,input$n2,input$n3)
createmydata(input$n)
})
output$data <- renderTable({
RE()
})
output$downloadData <- downloadHandler(
filename = function() {
paste(name, input$filetype, sep = ".")
},
content = function(file) {
sep <- switch(input$filetype, "csv" = ",", "tsv" = "\t")
write.table(RE(), file, sep = sep,
row.names = FALSE)
}
)
}
shinyApp(ui = ui, server=server)
As you can see, I'd like to download the output table to a csv or excel file... I let you try the code and then try to click on the download button, it does not work...
Debugging
When I run the code up above and attempted to download the data set, I received the following warning and error message in the Console Pane within RStudio.
Warning: Error in paste: object 'name' not found
Stack trace (innermost first):
1: runApp
Error : object 'name' not found
This led me to examine the paste() function used within the filename argument in shiny::downloadHandler(). In your code, you use the object name without ever assigning it a value.
I replaced name with the text "customTable" within the filename argument inside of downloadHandler().
output$downloadData <- downloadHandler(
filename = function() {
paste( "customTable", input$filetype, sep = ".")
},
content = function(file) {
sep <- switch(input$filetype, "csv" = ",", "tsv" = "\t")
write.table(RE(), file, sep = sep,
row.names = FALSE)
}
)
Downloading Data in Browser
After running the app.R script, I clicked on the Open in Browser button to view the Shiny app in a new tab on Chrome. Once there, I was successfully able to download both a .csv and .tsv file after hitting the download button.
Note: I'm looking for a better reason as to why this action needs to occur, but for now, I came across this relevant SO post Shiny app: downloadHandler does not produce a file.
I have an R shiny which generates a dashboard with some plots.
I implemented a download button to download the report as a PDF using knitr. Here is part the problematic part of the code:
hist_pl <- reactive({
inFile <- input$file
if (is.null(inFile))
return(NULL)
dataf <- getDF()
h <- hist(dataf)
par(new = T)
plot(x = h$mids, y=ec(h$mids)*max(h$counts), col = rgb(0,0,0,alpha=0), axes=F,xlab=NA, ylab=NA)
})
output$hist1 <- renderPlot({
hist_pl()
})
The problem is as follow:
When I comment the 'renderPlot' part of the code, the histogram appears normally in the PDF report (but not in the dashboard). When I uncomment it, the histogram disappear from the PDF (and appear in the dashboard).
The code for the download button is fairly simple:
output$report = downloadHandler(
filename = 'myreport.pdf',
content = function(file) {
out = knit2pdf('input.Rnw', clean = TRUE)
file.rename(out, file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
and the input.Rnw file:
\documentclass{article}
\begin{document}
<<names>>=
input$Val1
input$Val2
#
<<>>=
#output$mpgPlot ## N.B. This threw an error! Cannot call an object like this from shiny
print(hist_pl())
#
<<>>=
print(hist_pl())
#
\end{document}
Can someone tell me what could the problem be?
I have a Shiny app that reads in a gpx track file and buffers it. I then want the user to be able to download that shapefile to a destination of their choice. I have been trying to use the downloadHandler function, but so far I have no joy.
The name of the shapefile that I have created is called trk_buff.
Within R I can just use:
my_dsn<-"C:\\Documents\\TrackFiles"
writeOGR(obj=trk_buff, dsn=my_dsn, layer="BufferedTracks", driver="ESRI Shapefile")
I have tried to use the downloadHandler thus:
output$downloadData<-downloadHandler(
filename=function(file){trk_buff},
content=function(file){
writeOGR(obj=trk_buff, dsn=file, layer="BufferedTracks", driver="ESRI Shapefile")
})
But I am obviously doing something wrong as nothing happens... :|
EDIT TO ADD
I can get the behaviour I want if I use a combination of an action Button and a textFile box.
But that is a little clumsy and involves the user explicitly writing the filepath rather than searching for it, which will probably lead to errors:
e.g.
in the ui.R I have:
textInput("filepath","Filepath to download data"),
actionButton("act1","Download shapefile")
In the server.R I have:
action_btn_code <- eventReactive(input$act1, {
file_path<-input$filepath
writeOGR(obj=trk_buff, dsn=paste(file_path,"/Tracks",sep=""), layer="BufferedTracks",
driver="ESRI Shapefile", overwrite_layer=TRUE)
})
The following works for me. The idea is that you have to zip up of the shapefiles because downloadHandler can only handle downloading one file.
output$download_shp <- downloadHandler(
filename = "shapefile.zip",
content = function(file) {
data = trk_buff() # I assume this is a reactive object
# create a temp folder for shp files
temp_shp <- tempdir()
# write shp files
writeOGR(data, temp_shp, "trk_buff", "ESRI Shapefile",
overwrite_layer = TRUE)
# zip all the shp files
zip_file <- file.path(temp_shp, "trk_buff_shp.zip")
shp_files <- list.files(temp_shp,
"trk_buff",
full.names = TRUE)
# the following zip method works for me in linux but substitute with whatever method working in your OS
zip_command <- paste("zip -j",
zip_file,
paste(shp_files, collapse = " "))
system(zip_command)
# copy the zip file to the file argument
file.copy(zip_file, file)
# remove all the files created
file.remove(zip_file, shp_files)
}
)
library(sf)
library(zip)
output$download_shp <- downloadHandler(
filename <- function() {
"Data_shpExport.zip"
},
content = function(file) {
withProgress(message = "Exporting Data", {
incProgress(0.5)
tmp.path <- dirname(file)
name.base <- file.path(tmp.path, "BufferedTracks")
name.glob <- paste0(name.base, ".*")
name.shp <- paste0(name.base, ".shp")
name.zip <- paste0(name.base, ".zip")
if (length(Sys.glob(name.glob)) > 0) file.remove(Sys.glob(name.glob))
sf::st_write(trk_buff, dsn = name.shp, ## layer = "shpExport",
driver = "ESRI Shapefile", quiet = TRUE)
zip::zipr(zipfile = name.zip, files = Sys.glob(name.glob))
req(file.copy(name.zip, file))
if (length(Sys.glob(name.glob)) > 0) file.remove(Sys.glob(name.glob))
incProgress(0.5)
})
}
)
I have a file which i generate in shiny
The user clicks a button and the file should download. However nothing happens
The function export_report generates the excel file and saves it to a location. The function then passes back the file location to the download handler so it will download the file. The problem seems to be that it isnt being returned correctly. I have tested the function (export_report) outside of shiny and it returns everything perfectly so I'm clearly doing something wrong from the shiny perspective.
The file itself is created where it is supposed to be on the server because i can download it within RStudio and see it in the file explorer. Can anyone help
# UI Section
downloadButton("downloadRpt", "Download Report")
# Server Section
output$downloadRpt <- downloadHandler(
filename = function() {
mydf <- report()
dateRange <- input$dates_report
selection <- input$selection
myfile <- export_report (mydf, selection, dateRange)
},
content = function(file) {
file.copy(myfile, file)
}
)
I have seen other examples R Shiny: Download existing file which is what my code is based on
EDIT 1: Adding the export_report function with some fake data to run it
export_report <- function(mydf,selection,dateRange) {
# Template for where the template excel file is stored
myoutputTemplate <- '/home/shiny_tutorials/Save to Database/templates/output_template.xlsx'
start_date <- dateRange[1]
end_date <- dateRange[2]
date_range <- paste(start_date ,end_date, sep = " - " )
# Load workbook the template workbook
wb <- loadWorkbook(myoutputTemplate)
# write to the workbook the data frame
writeWorksheet(wb, mydf, sheet="Details",
startRow=8, startCol=2,
header=FALSE)
# add the the customer the user selected
writeWorksheet(wb, selection, sheet="Details",
startRow=3, startCol=3,
header=FALSE)
# date
writeWorksheet(wb, date_range, sheet="Details",
startRow=5, startCol=3,
header=FALSE)
# Create The file Name
filename <- paste(selection, Sys.Date(), sep = " - ") %>%
paste(.,"xlsx", sep = ".")
# removes the % sign and extra qoutes
filename <- gsub (pattern = '\'|%','', x = filename)
# output directory
myoutput <- paste('/home/shiny_tutorials/Save to Database/output/',
filename, sep = '')
# Save workbook
saveWorkbook(wb, myoutput)
# Return File Path
myoutput
}
To call the function you can use the data below
dateRange <- c("2011-09-23","2016-09-23")
selection = "COMPANY_A"
mydf <- iris
myfile <- export_report(mydf,selection,dateRange)
EDIT 2 I have now managed to get an error out of it. When i cat(myfile) in the filename = function() { section of the code i get the error after the correct file path has been returned
Warning in rep(yes, length.out = length(ans)) :
'x' is NULL so the result will be NULL
Warning: Error in ifelse: replacement has length zero
Stack trace (innermost first):
1: runApp
Error : replacement has length zero
This error is basically because my file path does not get passed to the segment myfile so
if someone can tell me how to get the filepath generated by my function to the server section of the code below, that should fix my problem
content = function(file) {
file.copy(myfile, file)
}
Thank you to everyone who commented and clarified my thinking a bit on how the download handler works.
In the end, i created a new function which split up the export function above
The new function i used is called generate_file() which simply returns the file name
generate_file_name <- function(selection) {
# Create The file Name
filename <- paste(selection, Sys.Date(), sep = " - ") %>%
paste(.,"xlsx", sep = ".")
# removes the % sign and extra qoutes
filename <- gsub (pattern = '\'|%','', x = filename)
# output directory
myoutput <- paste('/home/shiny_tutorials/Save to Database/output/',
filename, sep = '')
# Return File Path
myoutput
}
Then in the server side
output$downloadRpt <- downloadHandler(
filename = function() {
selection <- input$company
generate_file_name(selection)
},
content = function(file) {
mydf <- report()
dateRange <- input$dates_report
selection <- input$company
export_report(mydf,selection,dateRange)
myfile <- generate_file_name(selection)
file.copy(myfile, file)
}
)
This then finds the newly created file and exports it for the user
I just checked your problem with this example code and it worked:
output$downloadData <- downloadHandler(
filename = function() {
data <- mtcars
myfile <- "data.csv"
write.csv(data, myfile)
myfile
},
content = function(file) {
print(file) //prints: [...]\\Local\\Temp\\RtmpEBYDXT\\fileab8c003878.csv
file.copy(file, file)
}
)
myfile is the filename of the downloaded file. You cannot use it in file.copy as input, this variable is out of scope. It seems that R creates a temp file name (see the print()).
Try to use the filename function to define your path or a custom file name, and the write.csv in the content part. Example code:
output$downloadData <- downloadHandler(
filename = function() {
paste(<user_name or date for eg>, ".csv", sep="")
},
content = function(file) {
write.csv(data, file)
}
)
I noticed in your comment above, you have asked how the application would generate the correct file when used by multiple users. For this part, you need to use the session.
So if your business logic functions were to come from an R file called foo.R, the server code should look something like:
shinyServer(func = function(input, output, session) {
source("./foo.R", local=TRUE)
......
And this would separate out the session for each user, thereby generating files specific to each, when downloading. Hope this gives you some pointers.