Need simple UI Code in R - r

I have never created any UI in R, so need your help to create simple UI in R which has two browse buttons and Run button.
I have written the code to extract the fields from PDF files and gives the standardized the output in an excel file.
file_name1: it should select the filename from the first browse option.
file_name2: it should select the filename from the second browse option.
After browsing, it has to Run the program and back end my R code should execute.
After successfully execution, it has to show the timestamp: execution time in seconds and the message stating that "Successfully Completed"
Below is the R Code for the same:
#Fix the Working directory path:
setwd("D:/PROJECTS/PDF_TO_EXCEL_DEMO/")
#Calling required Libraries
source("CODES/CALL_LIBRARIES_v1.R")
################## IMPORTANT STEP ########################
# User has to update the filename here
file_name1="SAMPLE2017" #filename should take it from first browse option
file_name2="SAMPLE2018" #filename should take it from second browse option
file_ext=".pdf"
file_path="INPUTS/"
report_path="OUTPUTS/"
##########################################################
#Calling Prorams
source("CODES/CALL_PROGRAMS_v1.R")
#Removing all temp files from R
closeAllConnections()
rm(list=ls())

Related

Schedule a task (update data) each monday in Shiny

I have a dashboard living in a Shiny Server pro that shows different analysis. The data is coming from a long query that takes around 20 minutes to be completed.
In my current set up, I have a button that updates the data:
queries new data
transforms the data
saves the data in a file .RData
saves the data in a global object (using data <<-)
Just in case, outside the server and ui functions I have a statement that checks if data object exists. In case that does not exists, it reads the data from the .RData file instead of doing the query again.
Now I would like to update the data each Monday at 5:00pm (I do not want to open the app and push the button each Monday). I think that the best way to do it is using a cron job using cronR. The code will be located in the app.R outside the server and ui functions. Now I have the following questions:
If I am using Shiny server pro how many times, the app, will create the cron job if it is located in the app.R outside the server and ui functions?
How can I replace the object data in the shiny app? In such a way that if a user open the app on Monday after 5:00 pm the data will be in place, without the need of reading the .RData file and of course not doing the query again.
What is the best practice?
Just create your cron process with cronR completely outside the shiny application and make sure it saves your data to the correct place.
Create the R code which gets your data:
library(...)
# ...
# x <- mydata
save(x, file = "NewData.Rda")
Create the cron job:
cmd <- cron_rscript("path/to/getdata.R")
cron_add(cmd, frequency = 'daily', id = 'job5', at = '05:00')
I cant't see your point 1. The app will not create the cron job if it is not named "global.R" or "ui.R" or "server.R", I think. Also, you don't have to put your code under the /srv/shiny-server/ directory.
For your point 2., check the reactiveFileReader function from the shiny library. This function checks a file's last modified time and the file is re-read if changed
data <- reactiveFileReader(5*60*1000, filePath="NewData.Rda", readFunc = load)

How to avoid a rmd file to execute the entire R script every time I knit it to pdf?

Here is the question:
In file.r I ran an extensive analysis based on a huge dataset.
Every time I open the file I just need to load the libraries and everything is ready.
I don't need to download anymore any of the dataset inputs I need.
Now I have created a RMD file.rmd with the same code of file.r to present its findings.
I'm trying to get a preview of how the pdf will look like.
The problem is that when I click "Knit to pdf", it starts to download all the packages and datasets again. I have to wait hours to see the effects of small changes in code.
And there is more:
Some objects created in R file simply are not working in the rmd file.
Ex: in R file I coded:
edx2 <- edx2 %>% mutate(timeRr = yearRating - release)
When I try to run the same code in the rmd file I get the message:
Error in Func(x[[i]],...) : object 'timeRr' not found calls: f -> scales_add_defaults - > lapply - > fun
The same libraries loaded in both files (r and rmd)
What am I doing wrong?
1) At the end of the data analysis (file.R), save the data you need for the Notebook in a .RDS file.
For example, if you generated 3 results : res1, res2 and res3
results <- list(res1 = res1, res2 = res2, res3 = res3)
saveRDS(file = 'results.RDS', results)
2) instead of sourcing the analysis script, just read the results in the Notebook (.Rmd)
data <- readRDS('results.RDS')
# Results available for further use in the Notebook
data$res1
data$res2
data$res3
The error you get with edx2 is probably due to the fact that a new session is opened during generation of a notebook : are you sure that file.R really generates edx2, or is it only available in your current session?

Debugging R Scripts in azure-ml: Where can stdout and stderr logs be found? (or why are they empty?)

I'm using "studio (preview)" from Microsoft Azure Machine Learning to create a pipeline that applies machine learning to a dataset in a blob storage that is connected to our data warehouse.
In the "Designer", an "Exectue R Script" action can be added to the pipeline. I'm using this functionality to execute some of my own machine learning algorithms.
I've got a 'hello world' version of this script working (including using the "script bundle" to load the functions in my own R files). It applies a very simple manipulation (compute the days difference with the date in the date column and 'today'), and stores the output as a new file. Given that the exported file has the correct information, I know that the R script works well.
The script looks like this:
# R version: 3.5.1
# The script MUST contain a function named azureml_main
# which is the entry point for this module.
# The entry point function can contain up to two input arguments:
# Param<medals>: a R DataFrame
# Param<matches>: a R DataFrame
azureml_main <- function(dataframe1, dataframe2){
message("STARTING R script run.")
# If a zip file is connected to the third input port, it is
# unzipped under "./Script Bundle". This directory is added
# to sys.path.
message('Adding functions as source...')
if (FALSE) {
# This works...
source("./Script Bundle/first_function_for_script_bundle.R")
} else {
# And this works as well!
message('Sourcing all available functions...')
functions_folder = './Script Bundle'
list.files(path = functions_folder)
list_of_R_functions <- list.files(path = functions_folder, pattern = "^.*[Rr]$", include.dirs = FALSE, full.names = TRUE)
for (fun in list_of_R_functions) {
message(sprintf('Sourcing <%s>...', fun))
source(fun)
}
}
message('Executing R pipeline...')
dataframe1 = calculate_days_difference(dataframe = dataframe1)
# Return datasets as a Named List
return(list(dataset1=dataframe1, dataset2=dataframe2))
}
And although I do print some messages in the R Script, I haven't been able to find the "stdoutlogs" nor the "stderrlogs" that should contain these printed messages.
I need the printed messages for 1) information on how the analysis went and -most importantly- 2) debugging in case the code failed.
Now, I have found (on multiple locations) the files "stdoutlogs.txt" and "stderrlogs.txt". These can be found under "Logs" when I click on "Exectue R Script" in the "Designer".
I can also find "stdoutlogs.txt" and "stderrlogs.txt" files under "Experiments" when I click on a finished "Run" and then both under the tab "Outputs" and under the tab "Logs".
However... all of these files are empty.
Can anyone tell me how I can print messages from my R Script and help me locate where I can find the printed information?
Can you please click on the "Execute R module" and download the 70_driver.log? I tried message("STARTING R script run.") in an R sample and can found the output there.

Using Shiny fileInput to get path only

I have a very large fixed width file I need to read in using my Shiny application. The way my program is currently structured is the ui.R contains a fileInput allowing the user to locate the file using the browser.
On the server side, I only capture the path to the file such as the following:
path2file <- reactive({
infile <- input$path2file
if (is.null(infile)) return(NULL)
infile$datapath
})
A subsequent function takes that path as input and the proceeds to read in the file according to its layout specifications. This all works just fine; however when dealing with extremely large fwf files my program slows down tremendously and takes hours to get the path name of the file read in using fileInput
My suspicion is that fileInput is actually reading in the entire file and then my function only returns the datapath even though I am not explicitly reading in any file format type within the function.
My aim is to continue using the program as I have it structured now and obtain only the path to this file using my fileInput. I have found this topic on SO, and see it is a possible option.
Getting file path from Shiny UI (Not just directory) using browse button without uploading the file
However, I also aim to minimize the number of package dependencies I have; this has become a big issue and so if I MUST use an additional package I will, but I'd like to avoid that at all costs.
I experimented with this cheap trick:
path2file <- reactive({
infile <- input$path2file
if (is.null(infile)) return(NULL)
scan(infile$datapath, n = 1)
infile$datapath
})
Thinking that it would be a fast workaround, but it too is extremely slow so I suspect it too is not reading in only n = 1. So, my question is can anyone identify a way to use fileInput to allow a user to locate a file and have the server side function capture only the path and NOT read in the file or try and parse it in any way? More importantly, can this be done using functions in base R and Shiny alone without having to grab functions from other extended packages?
The above is the relevant portion of code in the server.R file and the relevant portion of code in the ui.R file is
fileInput('path2dor', 'Choose the DOR .txt file to format',
accept=c('text/csv',
'text/comma-separated-values,text/plain', '.csv')),
Thank you for you advice.
This functionality is not possible with fileInput. The reason is because 'fileInput' do not provide local path information to the server for security reasons.
With fileInput the user navigates through the browser on his local machine, the resulting file on the server side is the uploaded copy of the selected local once.
As an alternative you can use the shinyFiles package, which do navigate through the server side. This means, that you get all the paths on your local machine.
A second alternative could be a simple text input, which lets the user add a path by hand (make sure to check the path on the server side to not run into any troubles).
As pointed by others, due to security concerns shiny creates a tmp folder with all files loaded called with fileinput
Accordingly, you need to select all the files of interest in your folder and then call this tmp file with ...$datapath
Note however that each element of datapath will include both the directory information and the corresponding file name. Accordingly, you need to trim those paths to only account for the tmp directory. This can be achieved as follows...
Assume you will create an object called phu which will only contain the first file in the folder (using input$upload$datapath[1]) you called with fileInput("upload", NULL, buttonLabel = "Upload...", multiple = TRUE)
phu<-as.character(input$upload$datapath[1])
phu<-substr(phu,1,nchar(phu)-5)
The second line removes the last five characters in the string. These characters are 0.txt or whatever other extension you called in your input. The code provided only works with .txt files and requires the tm package. You can now use the object phu as the input directory of interest.
Finally, you need to call this output with an output object and print it in your ui this is shown with textOutput("Pdiretory") below.
The following example shows the entire process. Note that there are no security concerns because this temporary file and its content will be deleted at closing. Once more, the input files are .txt files.
library(shiny)
library(tm)
ui <- fluidPage(
fileInput("upload", NULL, buttonLabel = "Upload...", multiple = TRUE),
textOutput("Pdiretory")
)
server <- function(input, output, session) {
listdir <- eventReactive(input$upload, {
phu<-as.character(input$upload$datapath[1])
phu<-substr(phu,1,nchar(phu)-5)
txt<-Corpus(DirSource(phu),readerControl = list(language = "en"))
print(txt)
})
output$Pdiretory <- renderPrint ({
listdir()
})
}
shinyApp(ui = ui, server = server)

RShiny: How to pass variable from Server.R to an RMD script

I am playing around with RShiny recently, and I've built a working web interface that takes two parameters "date" and "location" and gives me back a series of graphs and tables from our database that fit the criteria.
What I would like to do with that, is to have users being able to download all the data and graphs in the form of a RMD report in HTML format.
so I have
1. UI.R with a download button
2. Server.R's downloadHandler starts my RMD script
3. ????
UI.R
downloadButton('downloadData','Download')
Server.R
output$downloadData<- downloadHandler(filename ="myData.html",
content= function(file= NULL){
knit(thread.RMD)
}
Here is the answer I got from the Shiny Google Group : https://groups.google.com/forum/?fromgroups=#!topic/shiny-discuss/XmW9V014EtI
The function that's given as the 'content' argument to downloadHandler takes one option, 'file'. When the download button is clicked, the download handler calls that function, and it uses the file argument to tell it where is should save the output file.
I don't see a way to set the output file name from knit2html(), but you can just rename it after it's created:
output$downloadData <- downloadHandler(
filename ="ShinyData.html",
content = function(file) {
knit2html("myreport.rmd")
file.rename("myreport.html", file)
}
)
(Also, you're missing a closing parenthesis in ui.r.)
-Winston

Resources