I need an R loop to continue running until the user presses a key. Something like the below. Any ideas? I'm new to R
while(FALSE_after_user_input){
queryWebApi()
Sys.sleep(1)
}
EDIT 1
What I'm really after is a way to stop data collection. I have a function I want to run every few seconds to query new data. The user needs the ability to stop the data collection loop.
readline() doesn't work as it halts execution of the data collection loop
Suggestion 1: TCL/TK
library(tcltk)
win1 <- tktoplevel()
butStop <- tkbutton(win1, text = "Stop",
command = function() {
assign("stoploop", TRUE, envir=.GlobalEnv)
tkdestroy(win1)
})
tkgrid(butStop)
stoploop <- FALSE
while(!stoploop) {
cat(". ")
Sys.sleep(1)
}
cat("\n")
Some code borrowed from: A button that triggers a function call.
Suggestion 2: Non-blocking checking on standard input. (Please be warned: C
is not my core competence, and I cobbled this together from bits on the internet.) The main idea is to write a function in C
that waits for user input, and call it from R
.
Snippet below adapted from Non-blocking user input in loop. Save the following code as kbhit.c
:
#include <stdio.h>
#include <unistd.h>
#include <R.h>
void kbhit(int *result)
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
*result = FD_ISSET(STDIN_FILENO, &fds);
}
Then, from the command line, run R CMD SHLIB kbhit.c
to compile it for R
.
Finally, in R
, load the newly created kbhit.so
, write a function (kbhit
) that returns the output from the C
function, and then run your loop. kbhit()
returns 0 unless it receives the enter key. Note that the only way to stop the loop is by hitting enter/return (or a hard break) -- if you want a more flexible approach, see the link above.
dyn.load("kbhit.so")
kbhit <- function() {
ch <- .C("kbhit", result=as.integer(0))
return(ch$result)
}
cat("Hit <enter> to stop\n")
while(kbhit()==0) {
cat(". ")
Sys.sleep(1)
}
More details on the .C
interface to R
.
On a Windows machine:
kbhit.c
#include <stdio.h>
#include <conio.h>
#include <R.h>
void do_kbhit(int *result) {
*result = kbhit();
}
In R
:
dyn.load("kbhit.dll")
kbhit <- function() {
ch <- .C("do_kbhit", result=as.integer(0))
return(ch$result)
}
cat("Hit any key to stop\n")
while(kbhit()==0) {
cat(". ")
Sys.sleep(1)
}
P.s. I hacked this together through Googling, so unfortunately I don't know how or why it works (if it works at all for you!).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With