Error with using if else inside function - r

I have problem in using if else inside function, my code is like this:
ConvertWgtZooLS <- function(WgtZoo, LSWay, Pos){
If(LSWay == 0){
NewWgtZoo <- WgtZoo
}else{
BackPos <- BackMatrix(Pos,1)
NewWgtZoo<- Ifelse((Sign(WgtZoo) * Sign(BackPos) * LSWay)>=0, WgtZoo, 0)
}
return(NewWgtZoo)
}
However, when I run that in R, error message appears as:
"Error: unexpected '{' in:
"ConvertWgtZooLS <- function(WgtZoo, LSWay, Pos){
If(LSWay == 0){"
How can I resolve this? What is the syntax problem there? I checked many websites and seems the above if else syntax is correct.
Thanks a lot!

The error in your code is that you have used If instead of if, and R is case-sensitive. Thus, it is possible to have another function named If that does something different from if, and, as #danielkullmann points out, that function is exactly what R is looking for.
The error messages that R produces are not always the most helpful, but in this case, it does point you very close to the problem area. It shows you where it got "confused" but it's up to you to figure out why!
After you've fixed that first problem, you'll find another one (for the same reason) on line 6, where you have written Ifelse instead of ifelse.
One last point: R is pretty whitespace friendly, so it is good practice to leave some space in your code to help improve legibility, particularly with if and else statements. Here's why:
I find if (LSWay == 0) { easier to read than if(LSWay == 0){
When using an actual function, like sum(x), you do not usually add a space, making it easier to spot these conditional statements in large blocks of code.
The Google R Style Guide is an interesting read in this regard.

Related

if...else (with exists()) in R function returning "unused argument" error

I am trying to learn to make different variations of basic functions on my own. However, despite my test statement defining "x" within if, the returning results did not execute the else correctly. I googled various tutorial sites such as DataCamp and Khan. The syntax, from what I can see, is correct. Was hoping someone out there may see differently and could explain why?
p <- function() {
if (!exists("x")) {
x <- "there is no number"
} else {
x <- "what do you want to add?"
}
x
}
Below is the screen shot of my console:
function with returning Error "Error in p(4) : unused argument (4)"
Various attempts:
I tried removing the "x" framing in my exists() but when I try to run p() , I get a Error in exists(x) : object 'x' not found and with p(4), it returned a Error in p(4) : unused argument (4)
I adjusted p <- function(x) as well, but then received for p() an Error in exists(x) : argument "x" is missing, with no default With p(4), an Error in exists(x) : invalid first argument
Removing the ! negation in exists() yielded a p() return of "what do you want to add?" and with p(4) an Error in p(4) : unused argument (4) again.
Should I not use exists() within the test statement after all? Did I make this unnecessarily complicated on myself?
Anna
So you definitely need to have an argument in your function. Plus I don't think you have to do all that assigning within the if/else statements. I think this gets what you're looking for, but not sure:
p <- function(some_object) {
if (!exists(some_object)) {
"there is no number"
} else
"what do you want to add?"
}
x <- 1 + 1
p("x")
It looks like a collaboration of both Bill and Ben's answers worked!
I gave up on using exists() and tabled it to master on another day. Meantime, with both codes merged, I got this:
p <- function(x) {
if (missing(x)) {
"there is no number"
} else
"what do you want to add?"
}
missing() was definitely a far friendlier function to use. I achieved the results I aimed for. p() returned a "there is no number" and p(4) returned a "what do you want to add?" At last!
Thank you both for helping me tackling what I thought was going to be a simple function. Clearly not! I'm going to tackle missing() and exists() ad nauseum and master this.
Much gratitude for the advice! I'm going to post the answer here in case another encounters the same snag.
Gratefully Yours,
Anna

How do I return to a certain line or argument in a function in R?

I have a function that validates a url based on input from a user. The way the function is set up, if the url doesn't validate (either because it doesn't exist or because it is a duplicate) the function simply ends.
How do I make it so that if the url isn't validated, the user goes back to the input dialogue to start the validation process over again instead of just ending the function?
exfun <- function(){
x <- toupper(readline("Do you want to do the function? Y/N......."))
if (x == "Y"){
writeLines("This is where the function body would be, but it's huge so for the sake of this StackExchange question, we'll just make it a simple thing")
} else
writeLines("Well then why did you start the function? We'll try this again")
#This is where I would like the function to return to the "x<-...." line.
There are a few places where I would like to be able to "return to line X" as there are at least two validation points. I have it set up as a series of if else arguments which else into a message. How can I make it else into a message and bring the user back to the beginning/a previous validation test?
I fiddled with the repeat function, but couldn't get it to return from if else correctly.
I'm not really answering your question, but I'll give you an example that might help you (and probably someone will give a hint to improve this).
You can set a while loop and put conditions to continue the loop or to end it, simply like this:
i <- 1
while (T) {
print(i)
i <- i + 1
if (i==5) {
print("NEXT")
next
}
if (i==10) break
}
As you see, the if with next conditions do something in your code, and keep running it after the command print("NEXT"). Also, the break is inside a condition to stop your loop.
I hope it helps, because with your example is difficult to give a full answer.

Is there a limit for the possible number of nested ifelse statements

I wrote a code that uses 75(!!!) nested ifelse statements.
I know its probably the most inefficient code I could write, but when I tried to run it I received the following error:
>Error: unexpected ')' in:
" ifelse(basic$SEMType=="ppc" &
(grepl("Wellpoint Prospecting",basic$CategoryName)), "Wellpoint Prospecting","other"
)))))))))))))))))))))))))))))))))))))"
I checked and doubled checked the number of ")". Its correct and the ifelse closes.
I also tried to run the nested ifelse by chunks, 15 at a time (and sometimes bigger chunks) and it works, so I figured the chance for syntax error is low.
Has anyone ever encountered such limitations?
I now run the code piece wise the inner ifelse first and record the result and move up the channel. This seems to work so far.
At least with this method, I seem to be able to create at most 50 levels of nesting
x<-"NA"
for(i in 1:50) {
x<-paste0("ifelse(x==",i,",",i,",", x, ")")
}
x
eval(parse(text=x), list2env(list(x=21)))
But if i try 51, i get the error
Error in parse(text = x) : contextstack overflow at line 1
so maybe that is specific to parse. It seems odd that you would get a syntax error.
Thanks to the link provided by #shadow, Brian Ripley confirmed this in a 2008 response to an r-help question
In this particular case [contextstack overflow], it is saying that you have more than 50 nested
parse contexts
And #Spacedman found where this limit is defined in the R source code
#define CONTEXTSTACK_SIZE 50

The function "else" in R

I am having some difficulty in using the function else in R.
When I input ?else, I didn't get any help about the function else.
When I run the following program:
i=1
if(i>1){print("aa")}
else{print("bb")}
the else didn't work. Can someone tell me the reasons?
to get help type
?'else'
look at the paragraph in help
Note that it is a common mistake to forget to put braces ({ .. }) around your statements, e.g., after if(..) or for(....). In particular, you should not have a newline between } and else to avoid a syntax error in entering a if ... else construct at the keyboard or via source. For that reason, one (somewhat extreme) attitude of defensive programming is to always use braces, e.g., for if clauses.
if(i>1){print("aa")
}else{print("bb")}
or
if(i>1){print("aa")}else{print("bb")}
will presumably work for you.
i=1
{
if(i>1){print("aa")}
else{print("bb")}
}
would also work. The key is to let the parser know to expect more input.

R Script - How to Continue Code Execution on Error

I have written an R script which includes a loop that retrieves external (web) data. The format of the data are most of the time the same, however sometimes the format changes in an unpredictable way and my loop is crashing (stops running).
Is there a way to continue code execution regardless the error? I am looking for something similar to "On error Resume Next" from VBA.
Thank you in advance.
Use try or tryCatch.
for(i in something)
{
res <- try(expression_to_get_data)
if(inherits(res, "try-error"))
{
#error handling code, maybe just skip this iteration using
next
}
#rest of iteration for case of no error
}
The modern way to do this uses purrr::possibly.
First, write a function that gets your data, get_data().
Then modify the function to return a default value in the case of an error.
get_data2 <- possibly(get_data, otherwise = NA)
Now call the modified function in the loop.
for(i in something) {
res <- get_data2(i)
}
You can use try:
# a has not been defined
for(i in 1:3)
{
if(i==2) try(print(a),silent=TRUE)
else print(i)
}
How about these solutions on this related question :
Is there a way to `source()` and continue after an error?
Either parse(file = "script.R") followed by a loop'd try(eval()) on each expression in the result.
Or the evaluate package.
If all you need to do is a small piece of clean up, then on.exit() may be the simplest option. It will execute the expression "when the current function exits (either naturally or as the result of an error)" (documentation here).
For example, the following will delete my_large_dataframe regardless of whether output_to_save gets created.
on.exit(rm("my_large_dataframe"))
my_large_dataframe = function_that_does_not_error()
output_to_save = function_that_does_error(my_large_dataframe)

Resources