I am working on a small Rscript that has a readLines function:
n <- readLines("stdin",n=1);
if (n =="y"){ ... }
I want to know if there is a way for R to go to the next part of the script without waiting for me to hit the ENTER button after I gave the input. In my script I only care whether I type in "n" or not.
Related
I have a readline() function in a for loop
For Simplicity let's say I have this code:
x <- character()
for (i in 1:500) x[i] <- readline('Enter Value')
How can I automatically enter input instead of manually entering it at the console 500 times?
readline() isn't intended for automatic input. From ?readline:
Description
readline reads a line from the terminal (in interactive use).
and:
Details
The prompt string will be truncated to a maximum allowed length,
normally 256 chars (but can be changed in the source code).
This can only be used in an interactive session.
Looking at ?interactive we can read the following:
An interactive R session is one in which it is assumed that there is a
human operator to interact with, so for example R can prompt for
corrections to incorrect input or ask what to do next or if it is OK
to move to the next plot.
So, basically you are trying to use readline for something it isn't intended for.
You can vectorize this command, assuming you're looking to fill the column with the same value. If that's not what you're trying to do, I'm confused as to what you want. Run my example below and say whether that's the kind of thing you're looking for
working <- iris
head(working)
working$like <- readline("Do you like this flower? ")
head(working)
I am not a programmer and have less than a month of experience with R but have been writing simple scripts that read from external CSV files for the past week. The function below, which reads data from a CSV file, was originally more complex but I repeatedly shortened it during troubleshooting until I was left with this:
newfunction <- function(input1, input2) {
processingobject <- read.csv("processing-file.csv")
print(head(processingobject))
}
I can print both the head and the entire processingobject within the script without a problem, but after the script ends processingobject no longer exists. It never appears in the RStudio global environment pane. Shouldn't processingobject still exist after the script terminates?
The script runs without displaying any error or warning messages. I tried assigning processingobject to a second variable: processingobject2 <- processingobject but the second variable doesn't exist after the script ends either. I also tried clearing the global environment and restarting RStudio, but that did not work either. If at the prompt after the script I type processingobject I get the message "Error: object 'processingobject' not found". The CSV file itself is perfectly normal as far as I can tell.
Obviously, I must be doing something very stupid. Please help me. Thanks.
You need to use return in your function and reproducible examples are always a good idea. It makes it easier for people to help you out.
ncol<- 10
nrow<- 100
x <- matrix(runif(nrow*ncol),nrow,ncol)
write.csv(x,file="example_data.csv")
newfunction <- function(input1) {
processingobject <- read.csv("example_data.csv")
result <- apply(processingobject,2,function(x)x*input1) #doing something to csv with input
print(head(result))
return(result)
}
newcsv <-newfunction(3)
I am working on a little interactive shell-like tool in R that uses readline to prompt stdin, like this:
console <- function(){
while(nchar(input <- readline(">>> "))) {
message("You typed: ", input)
}
}
It works but the only thing that bothers me is that lines entered this way do not get pushed upon the history stack. Pressing the up-arrow in R gives the last R command that was entered before starting the console.
Is there any way I can manually push the input lines upon the history stack, such that pressing the up-arrow will show the latest line entered in the console function?
I use this in rite to add commands to the command history. In essence, you can just savehistory and loadhistory from a local file. I do:
tmphistory <- tempfile()
savehistory(tmphistory)
histcon <- file(tmphistory, open="a")
writeLines(code, histcon)
close(histcon)
loadhistory(tmphistory)
unlink(tmphistory)
Note: Mac doesn't use history in the same way as other OS's, so be careful with this.
Is there a way to make R wait for console input before continuing?
Let's say I source two scripts like this in a main script called run.R:
# some more R Code here
source("script1.R")
source("script2.R")
# some more R Code there
Script1 contains some readLine statement that asks the user for a username.
Unfortunately if I just run the entire run.R file R doesn't wait for the username to be entered. It starts script2.R before the username is entered which leads to an error because the 2nd script needs the username.
I have an ugly workaround for this using R Studio's .rs.askForPassword which actually waits for the the input, but covers the password. Which is cool for passwords, but not so much for usernames. Plus it's an RStudio feature, not R.
readline can only be used in interactive sessions. In non-interactive use of readline the result is an empty string. On the help page of ?interactive you find the following about interactive sessions:
GUI consoles will arrange to start R in an interactive session. When R
is run in a terminal (via Rterm.exe on Windows), it assumes that it is
interactive if ‘stdin’ is connected to a (pseudo-)terminal and not if
‘stdin’ is redirected to a file or pipe. Command-line options
--interactive (Unix) and --ess (Windows, Rterm.exe) override the default assumption.
Try scan function.
This is test.R file:
y <- 2
cat('y=',y)
cat("\nEnter username")
x <- scan(what=character(),nmax=1,quiet=TRUE)
"ala ma kota"
y <- 2*2
cat('y=',y)
cat('\nx=',x)
and then I run this:
> source("test.R")
y= 2
Enter username
1: login
y= 4
x= login
--edit--
To read only one character quietly run this:
> x <- scan(what=character(),nmax=1,quiet=TRUE)
1: username
> x
[1] "username"
what sets the type, nmax sets the maximal numbers of elements to read and quiet determine if print a line, saying how many items have been read.
Why not putting
source("script2.R")
into the file script1.R?
When running this code:
library(TeachingDemos)
etxtStart(dir=getwd(), file="Nofunciona.txt")
etxtComment('Just a test')
for(i in 1:10){
cat("###",i,":\n")
my.sample = sample(100)
print(summary(my.sample))
qqnorm(my.sample)
etxtPlot(width=7.5)
}
etxtStop()
I only get a file named "Nofunciona.txt" with a text line "Just a test" and the commands to include the graphs, but nothing about the results of cat() or print(summary()), although I can see the results on the console.
If I change the loop using these two loops:
for(i in 1:10){
cat("###",i,":\n")
my.sample = sample(100)
print(summary(my.sample))
}
for(i in 1:10){
qqnorm(my.sample)
if(archivo) etxtPlot(width=7.5)
}
etxtStop()
Then I can obtain a file with the text results of cat(), and summary() and also the commands to include the graphs at the end. I know that with the last for loop I obtain ten times the same graph, that is not relevant.
It seems I cannot obtain graphical results and text results at the same time inside a for loop. Why does not the first code work?
Any idea?
Thanks.
The reason that is happening is because it is assumed that you do not want the etxtPlot command to show up in the transcript or command history, so when that function is called it sets a variable that tells the workhorse internal function (that is called by the task manager) to skip outputting the commands and results temporarily. This works correctly outside of a loop because the suppression of the output only lasts for the call to etxtPlot and everything else is properly output. The problem comes when you do this in a loop, everything done in the loop is processed in a single step (see ?addTaskCallback for the details on how things are handled), so the suppressing of the command and output from etxtPlot ends up also suppressing the commands and output from everything else in the loop.
A possible work around is to run the command:
trace(etxtPlot, edit=TRUE)
Then change the TRUE to FALSE in the second to last line of the code. Now you will see all the commands and output (including the calls to etxtPlot), but the plots will all come before the output (because the commands to include the plots are inserted at each iteration, but the other output is inserted after the loop has completed).
You might consider using the knitr package as an alternative, specifically the stitch or spin functions if you don't want to create a full template file, but just have some code processed. They don't do the realtime transcript, but deal better with automatic plot insertion.