R Shiny Save File by Unique Name - r

I have developed a Shiny app where users have the option to save machine learning models (to be able to use them later). These models get saved in the default shiny directory.
The issue is that, since the name of the model file being saved is not unique, the file can be overwritten when multiple users are using the app.
I want the files to be saved by a unique name and the users to be able to load their specific files back
Below is the code I am using
# Save model to be used later
.jcache(m1$classifier)
observeEvent(input$save, {
#delete previous model if it exists in folder
fn <- "m1"
if (file.exists(fn)) file.remove(fn)
save(m1, file = "D:\\Dropbox\\Users\\Myname\\m1")
})
#Load model saved earlier
load(file="m1")

There is a package called uuid that can help with this:
install.packages("uuid")
# This function will create a unique string for you that you can use as your filename
fn <- uuid::UUIDgenerate()
So I suggest generating a new filename each time you want to save a model and storing it in a variable that can be referred back to when you want to reload the model.
load(file=fn)

Related

How to have a user prompt accept a phyloseq-type file as dataframe?

I am trying to write an R script (to run from Rstudio by my students) that can accept a file of the phyloseq object type (is several tables connected to each other stored into one object) so I can use that object to run the code on. Since it seems like I cannot accept any phyloseq file directly, I decided to strip the file into 3 tables (of which are stored in the input file) like so
input <- as.data.frame(readline(prompt = "Enter phyloseq object name "))
input.taxtab <- as.data.frame(tax_table(input)) #tax_table is a ps-function that takes out the taxonomy table
input.otutab <- as.data.frame(input#otu_tab)
input.samdat <- as.data.frame(input#sam_data)
however, the obvious issues I see with my code are that the input file cannot store all the information, but it also (at the moment only seems to accept characters, i.e. it only takes the filename literally, not the file itself).
I have tried to get the data frames separately (by having 3 times the prompt input) but that doesn't coerce the file itself either. Here is a snippet of that:
input.taxtab <- as.data.frame(tax_table(readline(prompt = "Enter phyloseq object name ")))
Hope that someone can help me evolve my code to accept an actual file instead of its name

Writing and Saving to excel file with Shiny

My app allows a user to input a date range, a division, a pdf file, and an excel file. The program pulls numbers from the pdf, calculates total points, and adds it to the ranks pulled from the existing excel file. It is supposed to write and save the excel file. Without Shiny, my program works fine. Within Shiny, It is running and the data is correct, but it does not add the data to the excel file. I have added print prompts at various stages to test this. I have tried running this externally as well with the same results. It does not throw an error, it just not add the data to the excel file.
Server function
server<-function(input,output){
output$horse_div <- renderText({
paste("You have chosen",input$division)
})
output$qualifying<-renderText({
paste("Qualifying Period from",input$date[1],"to",input$date[2])
})
output$pdf<-renderText({
req(input$horsereport)
req(input$excelfile)
ponyoutput<-horseRecord(input$horsereport$datapath,input$date[1],input$date[2],input$division,input$excelfile$datapath)
paste("mylist",ponyoutput[1])
})
}
Snippet of horseRecord function
#Set up sheet and excel file
wsheetrank<-paste(div,"RANK")
wsheetpoints<-paste(div,"POINTS")
#load workbook
wb<-loadWorkbook(file=excelfile)
#add pony to ranked list
rank<-read.xlsx(excelfile,wsheetrank)
rank<-rank[,2:3]
rank<-rank %>% mutate(Points=as.numeric(Points))
dat<-rank
dat<-dat%>% add_row(Pony=horse,Points=points) %>% arrange(desc(Points))
#remove duplicates
dat<-dat[!duplicated(dat$Pony),]
rownames(dat)<-seq(from=1,to=nrow(dat),by=1)
#find rank
rank<-grep(horse,dat$Pony)
#Write to excel file
writeData(wb,sheet=wsheetrank,x=dat,colNames=TRUE,rowNames = TRUE,borders="all")
saveWorkbook(wb,excelfile,overwrite=TRUE)
This should add the totaled points pulled from the PDF file to the ranked list, resort, and write to the ranked worksheet. The full code and files can be found here: https://github.com/chealy21/horsePoints
The excel file that you upload gets saved in a temporary file on the shiny server. It is not the excel file that is on disk, even if you run your app locally.
If you add a browser() before writing the data in the workbook (line 138 of horsereportfunction.R), you will get a console prompt when the app reaches that line and you will be able to see it for yourself.
This is what is in the excelfile variable (on a linux machine. Windows temp file are somewhere else but they are still just tmp files):
excelfile
# [1] "/tmp/RtmpFllCQq/5709c4b043babf5b85bd29b4/0.xlsx"
This temporary file on the shiny server does get updated:
readxl::read_excel("/tmp/RtmpFllCQq/5709c4b043babf5b85bd29b4/0.xlsx") %>% filter(Pony == "BIT OF LAUGHTER")
# # A tibble: 1 x 3
# ..1 Pony Points
# <chr> <chr> <dbl>
# 1 30 BIT OF LAUGHTER 1503.
This is in line with the documentation for fileInput:
Whenever a file upload completes, the corresponding input variable is set to a dataframe. This dataframe contains one row for each selected file, and the following columns:
name:
The filename provided by the web browser. This is not the path to read to get at the actual data that was uploaded (see datapath column).
size:
The size of the uploaded data, in bytes.
type:
The MIME type reported by the browser (for example, text/plain), or empty string if the browser didn't know.
datapath:
The path to a temp file that contains the data that was uploaded. This file may be deleted if the user performs another upload operation.
Maybe you could let the user download the updated report (from datapath) after updating it?
If you never intend to publish your app and will always use it locally, you could hardcode the excel file directory. Your app would then copy the workbook at the hardcoded location from datapath.

how should i access n number of different .mat file in r by setting a proper path?

I have a total of 121 .mat files for some sonar experiment. I want to read each mat file by the iterative way and each iteration I want to access data from one particular mat file and work on corresponding data. I had already done with Matlab code the same thing I am trying in r.
This is my Matlab code
myFolder = 'G:\minor_project\Indrajeet\Data\ExpData\SingleChannel with
Array Steering\16 cell mesh slanting 30 deg';
% Check to make sure that the folder actually exists. Warn user if it doesn't.
if ~isdir(myFolder)
errorMessage = sprintf('Error: The following folder does notexist:\n%s', myFolder);
uiwait(warndlg(errorMessage));
return;
end
fpath = dir(fullfile( myFolder, '*.mat'));
filenames = fullfile(myFolder, {fpath.name});
Now if you observe carefully fpath variable you will find the first fullfile function takes myFolfer where my path is store and result in following or build full file name including .mat extension.
G:\minor_project\Indrajeet\Data\ExpData\SingleChannel with Array
Steering\16 cell mesh slanting 30 deg\*.mat
then "dir" function use the same folder name to create the list of (in the form of the structure of 121x1 struct which later I am accessing using dot.operator) all data.
Now I am learning the r programming and tried to mimic the same logic which is made in Matlab and initiated as
library(R.matlab)
myFolder = "G:/minor_project/Indrajeet/Data/ExpData/SingleChannel with
Array Steering/16 cell mesh slanting 30 deg";
if(!file.exists(myFolder))
{
print("Error: The following folder does not exist")
}
currently I know the "readMat" function only,is there any functions whcih will work same as fullfile and dir in r?if so,whcih packages this function belongs to

R extension write local data

I am creating a package and would like to store settings data locally, since it is unique for each user of the package and so that the setting does not have to be set each time the package is loaded.
How can I do this in the best way?
You could save your necessary data in an object and save it using saveRDS()
whenever a change it made or when user is leaving or giving command for saving.
It saves the R object as it is under a file name in the specified path.
saveRDS(<obj>, "path/to/filename.rds")
And you can load it next time when package is starting using loadRDS().
The good thing of loadRDS() is that you can assign a new name to the obj. (So you don't have to remember its old obj name. However the old obj name is also loaded with the object and will eventually pollute your namespace.
newly.assigned.name <- loadRDS("path/to/filename.rds")
# or also possible:
loadRDS("path/to/filename.rds") # and use its old name
Where to store
Windows
Maybe here:
You can use %systemdrive%%homepath% environment variable to accomplish
this.
The two command variables when concatenated gives you the desired
user's home directory path as below:
Running echo %systemdrive% on command prompt gives:
C:
Running echo %homepath% on command prompt gives:
\Users\
When used together it becomes:
C:\Users\
Linux/OsX
Either in the package location of the user,
path.to.package <- find.package("name.of.your.pacakge",
lib.loc = NULL, quiet = FALSE,
verbose = getOption("verbose"))
# and then construct with
destination.folder.path <- file.path(path.to.package,
"subfoldername", "filename")`
# the path to the final destination
# You should use `file.path()` to construct such paths, because it detects automatically the correct ('/' or '\') separators for the file paths in Unix-derived systems (Linux/Mac Os X) versus Windows.
Or use the $HOME variable of the user and there in a file - the name of which beginning with "." - this is convention in Unix-systems (Linux/Mac OS X) for such kind of file which save configurations of software programs.
e.g. ".your-packages-name.rds".
If anybody has a better solution, please help!

Use R package "googledrive" to load in R a file from my googledrive

I have a file in my google drive that is an xlsx. It is too big so it is not automatically converted to a googlesheet (that's why using googlesheets package did not work). The file is big and I can't even preview it through clicking on it on my googledrive. The only way to see it is to download is as an .xlsx . While I could load it as an xlsx file, I am trying instead to use the googledrive package.
So far what I have is:
library(googledrive)
drive_find(n_max = 50)
drive_download("filename_without_extension.xlsx",type = "xlsx")
but I got the following error:
'file' does not identify at least one Drive file.
Maybe it is me not specifying the path where the file lives in the Drive. For example : Work\Data\Project1\filename.xlsx
Could you give me an idea on how to load in R the file called filename.xlsx that is nested in the drive like that?
I read the documentation but couldn't figure out how to do that.Thanks in advance.
You should be able to do this by:
library(googledrive)
drive_download("~/Work/Data/Project1/filename.xlsx")
The type parameter is only for Google native spreadsheets, and does not apply to raw files.
I want to share my way.
I do this way because I keep on updating the xlsx file. It is a query result that comes from an ERP.
So, when I tried to do it by googleDrive Id, it gave me errors because each time the ERP update the file its Id change.
This is my context. Yours can be absolutely different. This file changes just 2 or three times at month. Even tough it is a "big" xlsx file (78-80K records with 19 factors), I use it for just seconds to calculate some values and then I can trash it. It does not have any sense to store it. (to store is more expensive than upload)
library(googledrive)
library(googlesheets4) # watch out: it is not the CRAN version yet 0.1.1.9000
drive_folder_owner<-"carlos.sxxx#xxxxxx.com" # this is my account in this gDrive folder.
drive_auth(email =drive_folder_owner) # previously authorized account
googlesheets4::sheets_auth(email =drive_folder_owner) # Yes, I know, should be the same, but they are different.
d1<-drive_find(pattern = "my_file.xlsx",type = drive_mime_type("xlsx")) # This is me finding the file created by the ERP, and I do shorten the search using the type
meta<-drive_get(id=d1$id)[["drive_resource"]] # Get the id from the file in googledrive
n_id<-glue("https://drive.google.com/open?id=",d1$id[[1]]) # here I am creating a path for reading
meta_name<- paste(getwd(),"/Files/",meta[[1]]$originalFilename,sep = "") # and a path to temporary save it.
drive_download(file=as_id(n_id),overwrite = TRUE, path = meta_name) # Now read and save locally.
V_CMV<-data.frame(read_xlsx(meta_name)) # store to data frame
file.remove(meta_name) # delete from R Server
rm(d1,n_id) # Delete temporary variables

Resources