Digital Geography

18. September 2012

R as a calculator: a little introduction to Tcl/TK programming with R

Due to an upcoming presentation about “what is R” and “what can I do with R” in my company I was playing around with GUIs as they are a very important way to interact with users and R to present a simple calculator. This will lead hopefully to an understanding of syntax and concepts in R:



My short overview over GUI packages led me to the gWidgetstcltk package which seems to be powerful and also easy to include.

require(gWidgetstcltk) #use the gWidgetstcltk package from CRAN

Now we will setup the GUI as a frame and an corresponding environment to store the variables:

env <- environment() #we will store our variables in this one win <- gwindow(title = "Calculator", width = 300, height = 300) [/sourcecode] lets get a structure for the buttons and the lines for input and results: [sourcecode language="R"] grp.variables <- ggroup(container = win) #this will be the "area" where we will put our input lines grp.buttons <- ggroup(container = win, horizontal = TRUE) #a container with horizontal order for included elements grp.buttons2 <- ggroup(container = grp.buttons, horizontal = FALSE) #we will group three containers in the "grp.buttons" container. each one with vertical order of elements to host the buttons grp.buttons3 <- ggroup(container = grp.buttons, horizontal = FALSE) #see above grp.buttons4 <- ggroup(container = grp.buttons, horizontal = FALSE) #see above grp.results <- ggroup(container = win, horizontal = TRUE) #a last group to contain the lines of result with an horizontal order [/sourcecode] Now we need some input fields for the variables x and y: [sourcecode language="R"] env$x<-gedit("x", cont = grp.variables) env$y<-gedit("y", cont = grp.variables) [/sourcecode] Due to the line-wise interpretation we need the functions which are associated with the later upcoming buttons beforehand! [sourcecode language="R"] handler.plus<-function(h) { #this is the function for addition of two elements x1<-as.numeric(svalue(env$x)) #convert the input in the input line env$x to a numeric value x2<-as.numeric(svalue(env$y)) #see above svalue(env$result)<-x1+x2 #this is the result } #end of the function with the title "handler.plus" [/sourcecode] Now we can go ahead and construct the other functions as well. the only “problem” is the division of two numbers x and y: [sourcecode language="R"] handler.div<-function(h) { x1<-as.numeric(svalue(env$x)) x2<-as.numeric(svalue(env$y)) if (x2==0) #now we will test whether the denominator equals zero gmessage("!denominator can´t be zero!") #show a message if this is the case else svalue(env$result)<-x1/x2 #else we don't have a poblem! } [/sourcecode] And a “close” button function: [sourcecode language="R"] handler_exit<-function(h,...) { dispose(win) } [/sourcecode] The last step is the organization of the buttons and output lines: [sourcecode language="R"] gbutton("+", cont=grp.buttons2, handler = handler.plus) #two buttons in each container except the exit button gbutton("-", cont=grp.buttons2, handler = handler.minus) gbutton("*", cont=grp.buttons3, handler = handler.times) gbutton("/", cont=grp.buttons3, handler = handler.div) gbutton("EXIT", cont=grp.buttons4, handler = handler_exit) #this will be located in its own group env$str<-glabel("your result is", cont = grp.results, expand=TRUE) #and the string indicating the result env$result<-glabel("NaN", cont = grp.results, expand=TRUE) #we will show the inital result with a "NaN" but this will be updated as a function by a button is called [/sourcecode] And now we are ready: [caption id="attachment_3007" align="aligncenter" width="300"] simple calculator in R[/caption]