I'm looking into having some user interaction in my code using RStudio. However, I'm running into some issues with the behavior of the command line in conjunction with the readline() function. Here's an example to illustrate my issue:
x <- 2
y <- 2
if (x == 2) { x <- readline("Put your x here: ")
} else { x <- 3 }
if (y == 2) { print("Something.")}
If I highlight this and hit "run" (or ctrl-alt-b at the end) to run line by line in the command line, I run into unexpected behavior shown here in the command line:
> x <- 2
> y <- 2
> if (x == 2) { x <- readline("Put your x here: ")
+ } else { x <- 3 }
Put your x here: if (y == 2) { print("Something.")}
Notice that on line 5, it skips right over the "Put your x here: " prompt (I did not input anything) and continues to the next line. Please do also note, however, when I "source" this code, the issue does not happen and the command line runs as expected (prompts me and waits until I input something).
Overall, this is a minor issue, but for testing purposes, it would be a major help to be able to run my user interaction code without having to source the entire file. Thanks for in advance!
Related
I have two questions regarding to exporting results to txt file.
First is, getting empty text file when using "sink" function with loop.
result is lists - summary(aov.res)
code below did make six text files, but nothing inside(empty text file).
i = 1
repeat{
tableA<-subset(coral, Location=="D7")
tableB<-subset(coral, Location==unique(coral$Location)[i])
tab<-rbind(tableA,tableB)
aov.res<-aov(cbind(AJ,A,DG,SG,EA)~Location*BvA,data = tab)
sink(paste("BA X CI", i,".txt"))
summary(aov.res)
sink()
if(i >= 6) break
i = i+1
}
so I had to do make code for each i. such like,
i=1
tableA<-subset(coral, BvA == "Before" & Location=="D7")
tableB<-subset(coral, BvA == "Before" & Location==unique(coral$Location)[i])
tab<-rbind(tableA,tableB)
aov.res<-aov(cbind(AJ,A,DG,SG,EA)~Location*Season,data = tab)
sink(paste("Short(bef) X CI","-Control vs D",i,".txt"))
summary(aov.res)
sink()
i=2
##same code as above, (tableA <-subset~~~~~~sink())
i=3
##same code as above,...
until i=6
Second is, how to make file name using variables.
Another approach I tried to solve the matter was using "capture.output" function.
However, bit stuck with making file name using variables(i), code is below.
i = 1
repeat{
tableA<-subset(coral, Location=="D7")
tableB<-subset(coral, Location==unique(coral$Location)[i])
tab<-rbind(tableA,tableB)
aov.res<-aov(cbind(AJ,A,DG,SG,EA)~Location*BvA,data = tab)
capture.output(summary(aov.res), file ="BA X CI", i, ".txt")
if(i >= 6) break
i = i+1
}
code (obviously...) produced "BA X CI" file though I wanted six files named "BA X CI n.txt" (n 1~6).
Does anyone give some tips please?? Thank you so much!!
I have the following code in the script test.R:
if (x==2){
stop("the script ends")
}
Now I source this script
source(test.R)
t <- 2
I would like the code to stop if x==2 and does not go further. However, it continues and assigns t <- 2. I can use the function warnings(options) but I want to avoid this option and implement a condition within the if. Any suggestion?
The code you list should work as expected.
As an example, I made two scripts, test.R and test2.R:
1. File test.R:
if (identical(x, 2)) {
stop("the script ends")
}
(Note: I'm using identical(x, 2) as the safer way to check whether x equals 2, but x == 2 would work the same in this example.)
2. File test2.R:
x <- 1
source("test.R")
t <- 1
print("This should be printed.")
x <- 2
source("test.R")
t <- 2
print("This should not be printed!")
Now I run test2.R from the console:
> t <- 5
> source('test2.R')
[1] "This should be printed."
Error in eval(ei, envir) : the script ends
> t
[1] 1
We see that the check passed the first time, when x == 1, and it failed the second time, when x == 2. Therefore, the value of t at the end is 1, because the first assignment was run and the second was not.
A while loop can create a condition that you can escape from as you are suggesting:
while (TRUE){
if (x==2) {
break
}
}
This is assuming that your code is 'all the way to the left' when executing. Seeing a little more might help, or better understanding how x is being set or being used. Note that using something like while(TRUE) might not be best practice, and can lead to infinite execution if you do not exit properly.
I am fairly new in R programming and want to grab keyboard entry to execute further programming codes. As the code as given here is executed, everything works all good but when the exit is entered the program is terminated and it didn't print y and z.
Could you please advise me how to use readline command in loop and execute other program lines after that loop?
n=1
a=1
y=c()
z=c()
x=""
while(x!="exit"){
x<-readline("Enter your name ")
library(stringr)
if(x!="exit" & str_detect(x,"N")){
y[n]=x
n=n+1
}else{
z[a]=x
a=a+1
}
}
print(y)
print(z)
This code works. I have copied it in a foo.R file as so :
# in "foo.R"
n = 1
a = 1
y = character()
z = character()
x = ""
library(stringr)
while (x!="exit") {
x <- readline("Enter your name\n")
if (x!="exit" & str_detect(x,"N")) {
y[n] = x
n = n+1
} else {
z[a] = x
a = a+1
}
}
print(y)
print(z)
And then, from my R console (with the proper working directory), I can run :
source("foo.R")
# Enter your name
# Bob
# Enter your name
# Nate
# Enter your name
# exit
# [1] "Nate"
# [1] "Bob" "exit"
and it seems to work just fine.
I use data checks in my code, for example the following one:
if (...)
stop(paste('Warning: Weights do not sum up to 1')
The problem is that if the condition is true and the warning appears in the console, the code does not stop running. If hidden in a long code, one needs to scroll up always in the console output to see if a warning appeared.
Is there a way to tell R to interupt ALL code when the stop warning appears and the condition is true? Something like BREAK ?
I do not represent a reproducible example here because my code is quite long.
EDIT:
Here is a mini example:
When I execute
a=1+2
if (a==3)
stop('a equals 3')
b=4
1+1
I would like to stop after printing
> a=1+2
>
> if (a==3)
+ stop('a equals 3')
Error: a equals 3
but R executes everything, also the last part:
> a=1+2
>
> if (a==3)
+ stop('a equals 3')
Error: a equals 3
>
>
> b=4
>
> 1+1
[1] 2
According to stop, it only stops evaluation of the current expression. While I agree with Roland's comment to encapsulate your code into meaningful pieces via functions, a quick hack would be to wrap all your current code in curly braces. That will make it appear to the R parser as a single expression.
R> # without curly braces
R> x <- 1
R> y <- 2
R> if (x < y)
+ stop("x < y")
Error: x < y
R> print("hello")
[1] "hello"
R>
R> # with curly braces
R> {
+ x <- 1
+ y <- 2
+ if (x < y)
+ stop("x < y")
+ print("hello")
+ }
Error: x < y
If I understand you correctly, it seems not to be the default behaviour of R.
So I think there is some change of the stop handler. You can try to call options(stop=NULL) before running your code. See the doc:
The default behaviour (the NULL error-handler) in interactive use is
to return to the top level prompt or the top level browser, and in
non-interactive use to (effectively) call q("no", status = 1, runLast
= FALSE).
At least the following code worked in my case (R 3.2.1):
funErr <- function() {
if (TRUE)
stop("now")
print("after stop")
}
funCaller <- function() {
print("before call")
funErr()
print("after call")
}
print("before global")
# Also possible to uncomment the following to test the `stop()`
# inside of `funErr()`
if(TRUE)
stop("global error")
funCaller()
I am trying to run an R script, using Rscript in Windows command prompt and ask for user's input.
So far, i have found answers on how to implement something similar in R's interactive shell. readline() or scan() doesn't seem to work for the command prompt.
Examples:
I have a polynomial y=cX where X can take more than one values X1,X2,X3 and so on. C variable is know, so what i need in order to calculate the value of y is to ask the user for the Xi values and store them somewhere inside my script.
The script bellow does nothing.
UIinput <- function(){
#Ask for user input
x <- readline(prompt = "Enter X1 value: ")
#Return
return(x)
}
The second example below just prompts the message and then ends.
FUN <- function(x) {
if (missing(x)) {
message("Uhh you forgot to eneter x...\nPlease enter it now.")
x <- readLines(n = 1)
}
x
}
FUN()
Console output:
Uhh you forgot to eneter x...
Please enter it now.
character(0)
Any suggestions?
Thanks in advance
cat("input x: ")
x <- readLines(con="stdin", 1)
cat(x, "\n")