z <- 5
count <- 0
while(z > 0 && z < 10){
X=rbinom(1,1, 0.5)
if(X == 1)
{
z <- z+1
}
else if(X == 0)
{
z <- z-1
}
count <- count+1
}
print(count)
Hi, this is my R script. I was wondering why when I type in:
source ('filename.R')
,there is no output in the console. But when I run another R script:
x <- 1:10
print(x)
it prints to the console.
I'm using Rx64 3.0.2. Thank you.
Try using: ?source
# This will echo all input and not truncate 150+ character lines..
source("filename.R", echo=TRUE,max.deparse.length=10000, continue.echo = getOption("continue"))
To amplify Prasanna's answer, here's the help file info:
echo logical; if TRUE, each expression is printed after parsing,
before evaluation.
print.eval logical; if TRUE, the result of eval(i) is printed for
each expression i; defaults to the value of echo.
Since the default value is echo=FALSE, you see nothing. This is a good default, since most of the time source is used to load functions rather than execute scripts, and people generally :-) don't want the function source splattered all over the console.
Related
So I am trying to learn R on my own and am just working through the online tutorial. I am trying to code a recursive function that prints the first n terms of the Fibonacci sequence and can't get the code to run without the error:
Error in if (nterms <= 0) { : missing value where TRUE/FALSE needed
My code does ask me for input before entering the if else statement either which I think is odd as well. Below is my code any help is appreciated.
#Define the fibonacci sequence
recurse_fibonacci <- function(n) {
# Define the initial two values of the sequence
if (n <= 1){
return(n)
} else {
# define the rest of the terms of the sequence using recursion
return(recurse_fibonacci(n-1) + recurse_fibonacci(n-2))
}
}
#Take input from the user
nterms = as.integer(readline(prompt="How many terms? "))
# check to see if the number of terms entered is valid
if(nterms <= 0) {
print("please enter a positive integer")
} else {
# This part actually calculates and displays the first n terms of the sequence
print("Fibonacci Sequence: ")
for(i in 0:(nterms - 1)){
print(recurse_fibonacci(i))
}
}
This is a problem of readline in non-interactive mode. readline does not wait for a keypress and immediately executes the next instruction. The solution below is the solution posted in this other SO post.
I post below a complete answer, with the Fibonnaci numbers function a bit modified.
recurse_fibonacci <- function(n) {
# Define the initial two values of the sequence
if (n <= 1){
n
} else{
# define the rest of the terms of the sequence using recursion
Recall(n - 1) + Recall(n - 2)
}
}
#Take input from the user
cat("How many terms?\n")
repeat{
nterms <- scan("stdin", what = character(), n = 1)
if(nchar(nterms) > 0) break
}
nterms <- as.integer(nterms)
# check to see if the number of terms entered is valid
if(nterms <= 0) {
print("please enter a positive integer")
} else {
# This part actually calculates and displays the first n terms of the sequence
print("Fibonacci Sequence: ")
for(i in 0:(nterms - 1)){
print(recurse_fibonacci(i))
}
}
This code is the contents of file fib.R. Running in a Ubuntu 20.04 terminal gives
rui#rui:~$ Rscript fib.R
How many terms?
8
Read 1 item
[1] "Fibonacci Sequence: "
[1] 0
[1] 1
[1] 1
[1] 2
[1] 3
[1] 5
[1] 8
[1] 13
rui#rui:~$
To make it work with Rscript replace
nterms = as.integer(readline(prompt="How many terms? "))
with
cat ("How many terms?")
nterms = as.integer (readLines ("stdin", n = 1))
Then you can run it as Rscript fib.R, assuming that the code is in the file fib.R in the current working directory.
Otherwise, execute it with source ("fib.R") within an R shell.
Rscript does not operate in interactive mode and does not expect any input from the terminal. Check what interactive () returns in both the cases. Rscript will return FALSE as it is non-interactive, but the same function when run within an R shell (with source ()) it will be true.
?readline mentions that it cannot be used in non-interactive mode. Whereas readLines explicitely connect to stdin.
The code works fine but you shouldn't enter it into the terminal as is. My suggestion: put the code into a script file (ending .R) and source it (get help about it with ?source but it's actually pretty straightforward).
In R-Studio you can simply hit the source button.
I did some programming work on R language to do the bubble sort. Sometimes it works perfectly without any error message, but sometimes, it shows "Error in if (x[i] > x[i + 1]) { : argument is of length zero". Can any one help me check whats wrong with it? I have attached my code below
example <- function(x) {
n <- length(x)
repeat {
hasChanged <- FALSE
n <- n - 1
for(i in 1:n) {
if ( x[i] > x[i+1] ) {
temp <- x[i]
x[i] <- x[i+1]
x[i+1] <- temp
hasChanged <- TRUE
cat("The current Vector is", x ,"\n")
}
}
if ( !hasChanged ) break;
}
}
x <-sample(1:10,5)
cat("The original Vector is", x ,"\n")
example(x)
The error occurs because you are iteratively decreasing n. Depending on the original vector's order (or lack thereof), n can reach the value of 1 after the last change. In that case, a further reduction of n in the next iteration step addresses the value x[0], which is undefined.
With a minimal correction your code will work properly, without giving error messages. Try to replace the line
if ( !hasChanged ) break;
with
if ( !hasChanged | n==1 ) break
Basically you have two termination criteria: Either nothing has been changed in the previous iteration or n is equal to one. In both cases, a further iteration won't change the vector since it is already ordered.
By the way, in R programming you don't need a semicolon at the end of a command. It is tolerated/ignored by the interpreter, but it clutters the code and is not considered good programming style.
Hope this helps.
Take this simple python script for example:
#!/usr/bin/env python3
# /tmp/xxx.py
import time
for i in range(1000):
print(i)
time.sleep(1)
It continuously outputs numbers. I can call it from R like this:
system2("/tmp/xxx.py", stdin=?)
where stdin can be set to NULL, "", TRUE or a filename. But what I am looking for is a way to process these numbers in realtime. For example, whenever a number is printed from this python script, I want to multiply the number by Pi and then print it to the console. Is there a way to do this in R?
Not an expert, but I got something working.
First of all, I used the following /tmp/xxx.R executable Rscript instead of your python script as I found out python was buffering its output (not printing one line at a time) which makes it hard to test:
#!/usr/bin/env Rscript
for (i in 1:5) {
cat(i, "\n")
Sys.sleep(1)
}
Then the R code:
system('mkfifo /tmp/xxx.fifo')
f <- fifo("/tmp/xxx.fifo", 'r')
p <- pipe('/tmp/xxx.R > /tmp/xxx.fifo; echo OVER > /tmp/xxx.fifo', 'w')
while(TRUE) {
line <- readLines(f, n = 1)
if (length(line) > 0) {
if (line == "OVER") break
cat(pi * as.numeric(line), "\n")
}
Sys.sleep(0.1)
}
close(f)
close(p)
some of which was inspired from this: https://stackoverflow.com/a/5561188/1201032.
Hope it answers your question.
Is it possible in R to do the following:
execute cmd1
if cmd1 generates error, proceed to:
execute cmd2
Thanks
try and/or tryCatch may be of use to you. Consider the super-simple toy example below:
# Our function just returns it's input as long as input is not negative otherwise an error is generated
f <- function(n) {
if( n < 0 )
stop("need positive integer")
return(n)
}
# Our alternative function to run if we get an error from the first function
f2 <- function(n) return( cat( paste( "You have a negative number which is" , n ) ) )
# Now we try to run it with `try`:
if( class( try( f(-1) , silent = TRUE ) ) == "try-error" )
f2(-1)
#You have a negative number which is -1
# And using the sophisticated `tryCatch()`
tryCatch( f(-1) , finally = f2(-1) )
#Error in f(-1) : need positive integer
#You have a negative number which is -1
The return value of try() is the value of the expression if it evaluates without error, otherwise an object of the class "try-error". In the first example we just check to see if an error was generated using comparing the class of the return value of try and execute f2() if an error was generated.
Note there are quite a few ways to handle this and I certainly wouldn't advocate either of these as being the best, but they should be a useful starting point for you to learn more about error handling.
Try this, err is the error message in the try block.
tryCatch(stop(),
error=function(err){
print(1)
print(err)
})
Depending on your use case, even simple short-circuiting of boolean operators might be enough. i.e., if your functions can return TRUE to indicate no-error and FALSE to indicate an error, then you can use the fact that || will only evaluate the RHS operand if the LHS operand evaluates to FALSE.
> doAwesomeStuff <- function() {cat("OMG, I'm awesome! <falls flat on face>\n"); FALSE}
> okDoNormalStuff <- function() {cat("OMG, I'm OK! :-)\n"); TRUE}
> doAwesomeStuff() || okDoNormalStuff()
OMG, I'm awesome! <falls flat on face>
OMG, I'm OK! :-)
[1] TRUE
But if doAwesomeStuff() works,
> doAwesomeStuff <- function() {cat("OMG, I'm awesome!\n"); TRUE}
> doAwesomeStuff() || okDoNormalStuff()
OMG, I'm awesome!
[1] TRUE
I'm trying to write an R script that takes in 3 arguments when run with Rscript: input file name, whether it has a header or not (values are 'header' or 'no_header', and a positive integer (the number of replacements; its for a bootstrap application). So, when I run it this way:
Rscript bootstrapWithReplacement.R survival.csv header 50
it should, before running, check if:
1) The script indeed took in 3 parameters;
2) whether the first parameter is a file;
3) whether the second parameter has a 'header' or 'no_header' value, and
4) if the number passed is a positive integer.
Here is my code so far:
pcArgs <- commandArgs()
snOffset <- grep('--args', pcArgs)
inputFile <- pcArgs[snOffset+1]
headerSpec <- pcArgs[snOffset+2] ## header/no_header
numberOfResamples <- pcArgs[snOffset+3] ## positive integer
check.integer <- function(N){
!length(grep("[^[:digit:]]", as.character(N)))
}
if (!file_test("-f",inputFile)) {stop("inputFile not defined. Proper use: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if (!exists("headerSpec")) {stop("headerSpec not defined. Proper use: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if (!exists("numberOfResamples")) {stop("numberOfResamples not defined. Proper use: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if ((headerSpec != 'header') == TRUE & (headerSpec != 'no_header') == TRUE) {stop("headerSpec not properly defined. Correct values: 'header' OR 'no_header'.")}
if (check.integer(numberOfResamples) != TRUE | (numberOfResamples>0) != TRUE) {stop("numberOfResamples not properly defined. Must be an integer larger than 0.")}
if (headerSpec == 'header') {
inputData<-read.csv(inputFile)
for (i in 1:numberOfResamples) {write.csv(inputData[sample(nrow(inputData),replace=TRUE),], paste("./bootstrap_",i,"_",inputFile,sep=""), row.names=FALSE)}
}
if (headerSpec == 'no_header') {
inputData<-read.table(inputFile,header=FALSE)
for (i in 1:numberOfResamples) {write.table(inputData[sample(nrow(inputData),replace=TRUE),], paste("./bootstrap_",i,"_",inputFile,sep=""),
sep=",", row.names=FALSE, col.names=FALSE)}
}
My problem is, the check for the existence of a file works, but for the header or integer don't.
Also, how can I, in the beginning, check if all three arguments have been passed?
Thanks!
As Vincent said, you should use the trailingOnly argument to commandArgs to simplify things.
As Konrad said, never, ever, ever compare directly to TRUE and FALSE.
Also, use assertive for doing assertions.
library(assertive)
library(methods)
cmd_args <- commandArgs(TRUE)
if(length(cmd_args) < 3)
{
stop("Not enough arguments. Please supply 3 arguments.")
}
inputFile <- cmd_args[1]
if (!file_test("-f", inputFile))
{
stop("inputFile not defined, or not correctly named."
}
headerSpec <- match.arg(cmd_args[2], c("header", "no_header"))
numberOfResamples <- as.numeric(cmd_args[3])
assert_all_numbers_are_whole_numbers(numberOfResamples)
assert_all_are_positive(numberOfResamples)
message("Success!")
I managed to solve all the checks, here's how:
if ((length(pcArgs) == 8) == FALSE) {stop("Not enough arguments. Please supply 3 arguments. Proper use example: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if (!file_test("-f",inputFile)) {stop("inputFile not defined, or not correctly named. Proper use example: Rscript bootstrapWithReplacementFile.R survival.csv header 50.")}
if ((headerSpec != 'header') == TRUE & (headerSpec != 'no_header') == TRUE) {stop("headerSpec not properly defined. Correct values: 'header' OR 'no_header'.")}
if (check.integer(numberOfResamples) != TRUE | (numberOfResamples>0) != TRUE) {stop("numberOfResamples not properly defined. Must be an integer larger than 0.")}
Thanks everyone!