I am creating a package in R that will have a GUI interface through the tcltk package. A front end function will get the data from the user through a GUI and call a back end function which returns the results back to the front end. I currently have written all of the documentation for the functions, and except for this part and a bit of bug testing the functions are also complete.
To help the user out, I want to be able to print the documentation. In Rstudio this displays it in the help window (it is important to note that this window is not created by my code through the tcltk package, this window is a part of Rstudio).
If my function only interacts with the user through the command line, I can get the help screen in Rstudio to update immediately. However, if I am using the graphics, the help window won't update until after the function is done, which defeats the purpose of having it print the help screen in the first place.
Below is an example of a GUI window created through the tcltk package. I'm using var.test as an example documentation here, so make sure your help window is on something else to see when the help screen updates.
require(tcltk)
print(help(var.test))
hi <- tktoplevel() #creates a window
ok <- function() # this function is called by pushing the button defined below
{
print("Goodbye, World!")
tkdestroy(hi) # destroys the window
}
print("Hello, World!")
ok.button <- ttkbutton(hi, text = "This is a button", command = ok) #defines the button
tkgrid(ok.button) #puts the button on the window "hi"
tkfocus(hi)
tkwait.window(hi)
As you can see, even calling the help function first, before the tcltk graphics window is even created, doesn't make the help window update. The print function still seems to work, as "Hello, World" is printed before one presses the button.
For my functions to work properly, I must use the tkwait.window(), otherwise the front end won't sync with the back end.
If getting the Rstudio window to update isn't really possible, then an alternative solution that uses a different window or program would be acceptable.
Add a small delay into your code after trying to print the help:
....
print(help(var.test))
# Sys.sleep(0.01) # too short
Sys.sleep(0.5) # long enough
...
This works in Linux and Windows...
I guess RStudio is not updating the GUI while executing the R command batch (all commands that you send to R at once) because it blocks updates executes R in a "blocking sub thread" and therefore behaving like "single threading" so that the GUI cannot be updated until the execution of the R batch ends.
The sleep function seems to return the control to the RStudio (GUI?) process so that it can update the GUI.
If you reduce the sleeping time too much you can observe partial updates of the RStudio GUI.
PS: Using process.events() does not work!
Related
I actually want to take input from R in script mode (i.e. I'll copy and run the program written in an RScript) and I am using the readLines function for that (since I've come to know that readline function is meant to be used only in interactive mode). When I run the following code (in rstudio),
k = as.integer(readLines("stdin",n=1))
x = c()
it starts taking input, but the problem is that it doesn't stop taking input. Even if I click on the red octagon, it is not stopping and neither am I able to quit the session. I've to restart the computer. Any help on how can we stop it?? (I'll also be very happy if you suggest some better function to take and process input in script mode)
I am used to starting all my Matlab scripts with clear all; close all; clc to ensure I am not looking at any old data or plots. I found Julia's clearconsole() to be equivalent to Matlab's clc, but don't have working solutions for the other two Matlab commands yet. I mostly work in the Juno IDE and run scripts with the Play ("Run All") button.
The Revise.jl package is supposed to clear the workspace now that workspace() is deprecated, but it doesn't work for this simple test case. If I define x once and then comment that line out, it will continue to print each time I run without error.
using Revise
clearconsole()
#x=1
println(x)
I know I can hit "Stop" then "Play" to reset the workspace. However, that still doesn't close old plots, and the time to first plot issue makes this option undesirable.
I found the "Forget All Plots" button in Juno's plot pane, but I would like to have that functionality as a line in my script instead. Currently, it takes me three clicks to run a script again after I edit it (four if I include "Stop").
"Forget All Plots"
Somewhere in the editor to put focus back on my current file.
"Run All"
I would ideally like to rerun in a fresh environment with one click or keystroke, but any tips on a better Juno workflow would be appreciated.
My question was answered on the Julia discourse website: link.
Juno.clearconsole() may be used like Matlab's clc.
Writing a script within a module will clear the variables upon each run like Matlab's clear all.
A new function may be added to Juno.jl in the future which will work like Matlab's close all.
I often include View() statements in my R scripts. If I accidentally forget the closing bracket at the end of the line, and then run the line of code from the script window using ctrl-enter, R just keeps trying to execute the remainder of my script. I don't know why it does that (rather than using the + symbol to prompt me to provide further input).
Moreover, I've tried to stop this by setting break points in my code - I can click on the LHS of the page and a little red circle appears. But the breakpoints don't seem to work - R just ignores them and keeps going.
The only way I can get out of it is by killing the process in the Windows task manager and then going back in afterwards. But it's wasting a lot of time.
Does anyone know how I can fix this please?
Thank you.
In effect, what your function is processing looks like that:
... %>% View(
lm(am~cyl, mtcars)
...
...
As R can't find the bracket for ) it includes remaining statements as input to View and searches for the bracket.
Solutions
Kind of depends on what you want to do with those scripts but if the intention is to run them in the background consider using callr. This package lets you run R from R and offers kill methods to kill the process you started that way.
On Windows pressing Esc should enable you to get back to the console but if it's a memory intense process it may be difficult.
You may try pressing Ctrl+c in order to kill the process.
I'm running an R script via my Linux Mint 16 command line. It contains a boxplot that I want to display in a window. So I'm using x11() function for creating that window. Here is my code:
testdata <- data.frame(sample(1:1000,size=100,replace=T), row.names=NULL)
colnames(testdata)<-c("data")
x11()
boxplot(testdata, main="Boxplot der Testdaten", horizontal=TRUE)
When I run this function in Rstudio, it will open a window and show the boxplot created. But whenever I run it from the command line of my Linux Mint 16 machine, the window will open for a second and then close again. I can see the boxplot for a second. I couldn't really find a reason for this. I'm quite new to R and never used X11 before. Any ideas would be really appreciated. Thanks!
This is more-or-less a FAQ. Part of this is that you seem to misunderstand how all commands terminate. I.e. when you call ls it does not stop either.
So here you need to something extra. Possibly approaches:
Just sleep via Sys.sleep(10) which would wait ten seconds.
Wait for user input via readLines(stdin()) or something like that [untested]
Use the tcltk package which comes with R and is available on all platforms to pop up a window the user has to click to make the click disappear. That solution has been posted a few times over the years on r-help.
But in this day and age, you may also rethink the issue. I had good success preparing analysis and visualization for colleagues via the most-awesome shiny package which displays to a web page. Everybody has a web browser...
You can sleep until all windows are closed
while(names(dev.cur()) !='null device') Sys.sleep(1)
on my machine, after calling x11(), names(dev.cur()) is "X11cairo". After closing all/any windows opened with x11, names(dev.cur()) becomes "null device"
testdata <- data.frame(sample(1:1000,size=100,replace=T), row.names=NULL)
colnames(testdata)<-c("data")
x11()
boxplot(testdata, main="Boxplot der Testdaten", horizontal=TRUE)
# wait until window is closed (check every second)
while(names(dev.cur()) !='null device') Sys.sleep(1)
I am familar with matlab, but relatively new to r. I have an r script which produces many different graphical plot windows and takes some time in between each one. While this is running, I tend to be working on other things. The problem is every time a new graphics window is produced, it steals the focus, redirecting keyboard input away from what i am doing. Is there a way in r to prevent focus stealing when a graphical plot is produced?
I have searched everywhere but failed to find any reference to this. I am working in linux.
Any help greatly appreciated.
Thanks
Only on Windows: try putting a bringToTop(-1) in your function:
z <- function() {
plot(1:3)
bringToTop(-1)
}
z()
It will temporarily steal focus but then return it.
Another strategy on Windows:
z <- function(){
windows(restoreConsole=TRUE)
plot(1)
}
z()
I'm still thinking here...
If you are more interested in doing something else while the plots are being produced then I would suggest opening a pdf device so that all the plots go to a pdf file in the background and do not interfere with whatever else you are doing. Then when you are ready to look through the plots you just open the pdf file and look at the plots (and you can easily go back to previous plots this way).
If wmctrl is installed on your system, you can avoid losing focus by redefining the plot function like this:
plot <- function(...) {
graphics::plot(...)
system("wmctrl -a :ACTIVE:")
}
It seems to work quite well, in the fluxbox window manager at least. I tried different scenarios like switching to a different window during a long calculation before plot is called, and opening multiple plots.
Put it into your .Rprofile if you want it to persist.