TclTk object in R - r

I'm new to R (and programming in general), so apologies if this has been answered elsewhere. I was not able to find an answer via searching, but any help or direction would be great!
I'm trying to make a clickable interface in R, where I can have users click to find a file of choice that proceeds to get automatically analyzed in R.
Here's what I'm having trouble with:
require(tcltk)
getfile <- function() {name <- tclvalue(tkgetOpenFile(
filetypes = "{{CSV Files} {.csv}}"))
if (name == "") return;
datafile <- read.csv(name,header=T)
}
tt <- tktoplevel()
button.widget <- tkbutton(tt, text = "Select CSV File to be analyzed", command = getfile)
tkpack(button.widget)
# The content of the CSV file is placed in the variable 'datafile'
Yet when I try to execute it, and click on a CSV file of interest after the button pops up, nothing happens. By that I mean R gives me the error below when I type in datafile.
Error: object 'datafile' not found
Once again, any help is much appreciated. Thanks!

The top level object has an environment in which you can store things, keeping them local to the GUI. Give your callbacks that object as an argument:
# callback that reads a file and stores the DF in the env of the toplevel:
getfile <- function(tt) {name <- tclvalue(tkgetOpenFile(
filetypes = "{{CSV Files} {.csv}}"))
if (name == "") return;
tt$env$datafile <- read.csv(name,header=T)
}
# callback that does something to the data frame (should check for existence first!)
dosomething <- function(tt){
print(summary(tt$env$datafile))
}
# make a dialog with a load button and a do something button:
tt <- tktoplevel()
button.choose <- tkbutton(tt, text = "Select CSV File to be analyzed", command = function(){getfile(tt)})
tkpack(button.choose)
button.dosomething <- tkbutton(tt, text = "Do something", command = function(){dosomething(tt)})
tkpack(button.dosomething)
That should be fairly robust, although I'm not sure if there's anything already in the environment that you should beware stomping on, in which case create an environment in that environment and use that for your local storage.
If you want to quit the dialog and save things for the user, prompt for a name and use assign to store them in .GlobalEnv on exit.

Related

.rdata object load and use the variable through R shiny

I am trying to load the .rdata object through user input , if the object is found then get the length of the list that is stored in the object else length is 1.
I am using the below code:
output$M_name<-renderUI({
if(file.exists(obj_name())==TRUE)
{
modname<<-load(file=objname,envir=sys.frame())
ver<<- length(get(modname))+1
str1 <- paste0("- ",isolate(input$model_name)," already EXISTS.")
str2 <- paste("- Please upload the new data csv file of the above mentioned model")
HTML(paste(str1, str2, sep = "<br/>"))
}else
{
modname<<-isolate({input$model_name})
ver<<-length(get(modname))+1
str1<-paste0("- ",isolate(input$model_name)," does not EXIST")
str2<-paste("- Please use the same name, if you have already uploaded base model details before")
str3<-paste("- If this is the first time, Please upload the csv file on the next page")
HTML(paste(str1, str2, str3, sep = "<br/>"))
}
})
The file gets loaded and the object is saved in "modname" but i do not see the "ver" variable in the r environment.
I am fairly new to R shiny, please bear with my coding.

Change tklabel to file name opened by tkbutton function in R

I am working on creating a widget in R that can open a file and show the characteristics of that file within the same widget. I want this information to be updated automatically when loading the file. This means that I have the following function for the button that can open the file:
getfile <- function() {
name <- tclvalue(tkgetOpenFile(
filetypes = "{{raster files} {.tiff .tif .img .grd}} {{All files} *}"))
if (name == "") return;
Sys.sleep(10)
assign("Filename", name, envir = .GlobalEnv)
tclvalue(Filename) <- name
}
the function for the button that opens this file is:
button.widget <- tkbutton(tt, text = "Select File", command = getfile)
tkgrid(button.widget, pady=10, padx=10, columnspan=3)
The label is given by:
Filename <- tclVar("")
label.widget <- tklabel(tt, text=tclvalue(Filename))
tkgrid(label.widget, row=2, column=0)
However, when I create the widget everything works, Filename is changed and a file can be opened. But the text in the label is not changed. How can i fix this? Is there an event that can be run when I close the OpenFile dialog window?
Try:
tklabel (tt, textvariable=Filename)
There is this example where he configures the label as text first then reconfigures it with a textvariable. But you should be able to configure it as a textvariable initially. Caveat: I don't know R.
The alternative option is to put:
tkconfigure(label.widget,text=tclvalue(Filename))
At the end of the getfile() function.

How to save a data frame as CSV to a user selected location using tcltk

I have a data frame called, Fail.
I would like to save Fail as a CSV in a location that the user selects. Below is some example code that I found, but I don't know how to incorporate Fail into it.
require(tcltk)
fileName <- tclvalue(tkgetSaveFile())
if (!nchar(fileName)) {
tkmessageBox(message = "No file was selected!")
} else {
tkmessageBox(message = paste("The file selected was", fileName))
}
Take a look at the write.csv or the write.table functions. You just have to supply the file name the user selects to the file parameter, and the dataframe to the x parameter:
write.csv(x=df, file="myFileName")
You need not to use even the package "tcltk". You can simply do as shown below:
write.csv(x, file = "c:\\myname\\yourfile.csv", row.names = FALSE)
Give your path inspite of "c:\myname\yourfile.csv".
write.csv([enter name of dataframe here],file = file.choose(new = T))
After running above script this window will open :
Type the new file name with extension in the File name field and click Open, it'll ask you to create a new file to which you should select Yes and the file will be created and saved in the desired location.

How do I update a gedit box instantly after using gfile to specify a filepath, using gWidgetsRGtk2, in R

I am trying to create a GUI using gWidgetsRGtk2 for a program that I have written in R. My GUI has a gedit() text box in which the user can type a file path for the input data file to be put into the program. It also has a 'browse' button, which, when clicked, opens up a gfile() box so that they can browse for the file that they want. What I am having trouble with is updating the value in my gedit() box, after the user has selected their file using the 'browse' button. The code below may make this clearer:
dir <- getwd()
sfilepath <- paste0(dir,"/")
win = gwindow("Set Parameters:",width=400,height=550)
nb = gnotebook(cont=win)
tab2 <- glayout(cont=nb, label = "Advanced Settings")
tab1 <- glayout(cont=nb, label = "Basic Settings")
tab1[2,2] <- glabel("BD:",cont=tab1)
tab1[2,4:5] <- gedit(1,cont=tab1)
addhandlerkeystroke(tab1[2,4],handler=function(h,...){BD <<- as.numeric(svalue(h$obj))})
tab1[3,2:5] <- gseparator(cont=tab1)
tab1[4,2:5] <- glabel("File path:",cont=tab1)
tab1[5,2:4] <- gedit(paste0(dir,"/"),cont=tab1)
tab1[5,5] <- gbutton(text="Browse", handler=function(h,...){ gfile("Select a file",type="open", filter = list("text files" = list(patterns = c("*.csv","*.txt")), "R files" =list(patterns = c("*.R","*.Rdata"))), handler = function(h,...){ sfilepath <<- h$file},cont=TRUE)},cont=tab1)
addhandlermousemotion(tab1[5,2],handler=function(h,...){svalue(h$obj) <- sfilepath})
So far I have tried using addhandlermousemotion, as in the code above, so the text in the gedit() box is only updated when you move the mouse over the box itself. However, I would prefer it if the text in the box updated instantly.
I have also tried using addhandleridle(), with an interval of 1 second, so that the text in the box will be automatically updated every 1 second. This worked. However, it made it impossible to type in the box properly, because the text box was being updated with the old 'sfilepath' before it had saved the new 'sfilepath' that was being typed in.
I am a beginner at making at GUIs (I have written a program for work, but it needs to be used by someone else once I leave, so decided last Friday that I should figure out how to make it into a GUI). So any help that anyone can offer would be greatly appreciated.
Here is the pattern you want (passing a handler to gfilebrowse):
w <- gwindow("test")
g <- ggroup(cont=w, horizontal=FALSE)
file_upload <- gfilebrowse(cont=g, handler=function(h,...) {
svalue(e) <- svalue(h$obj)
})
e <- gedit("", cont=g)

Interactively ask user for filename before saving file

I want to save the my tab delim files manually. I mean that I want user to choose the directory and file name when he wants to save the data. (For an example I have merged individual files into single file and want to save it.)
Usually I use write.table but in write.table we define the directory path and file name within that function but I want a function in which user can save file with any name in his desired directory.
Just use the file.choose() function,like this:
write.table(yerdata, file = file.choose(new = TRUE))
On Windows, at least, that will bring up a dialog for save-as commands.
Annoyingly the tcltk package doesn't have a function for 'Save As', it only has a file selector for choosing an existing file.
Luckily you can take the DIY approach via some tcl calls:
require(tcltk)
write.table(yerdata,file = tclvalue(tcl("tk_getSaveFile")))
The tk_choose.files function source could be used as a template to write a nicer interface to tcl("tk_getSaveFile") if needed. Does seem to be a glaring omission in package:tcltk though...
Using gWidgets:
gfile("Save yerdata", type = "save", handler = function(h, ...)
{
write.table(yerdata, file = h$file)
})
One (perhaps less than ideal) option would be to use readline to prompt the user for the full path and file name (or just the file name if you want to programmatically choose the directory) and then simply pass that value on the write.table. Here's a sketch:
FILE_PATH <- readline(prompt = "Enter a full path and file name: ")
#Some checking to make sure you got a valid file path...
write.table(yerdata, file = FILE_PATH)
Note that as per ?readline this will really only work when running R interactively.
As it is 2017 now, the tcltk2 package is an improvement of tcltk:
library(tcltk2)
filename <- tclvalue(tkgetSaveFile())
if (!nchar(filename)) {
tkmessageBox(message = "No file was selected!")
} else {
tkmessageBox(message = paste("The file selected was", filename))
}
And the use of filters, let's say one should only save as JPG/JPEG:
jpeg_filename <- tclvalue(
tkgetSaveFile(initialfile = "foo.jpg",
filetypes = "{ {JPEG Files} {.jpg .jpeg} } { {All Files} * }")
)

Resources