Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
176 views
in Technique[技术] by (71.8m points)

r - if/else constructs inside and outside functions

When I look at R functions I often find the following structure:

f <- function(exp=T) {
  if (exp)
    a <- 1
  else
    a <- 2
}
f()
f(F)

This will run without error. But executing the inner function code throws an error as R probably assumes that the statement is finished after the first assignment a <- 1 and cannot handle the following else.

exp=T
if (exp)
  a <- 1
else
  a <- 2

Now, this makes sense to me, but I still would like to understand why the behaviour of the executed code differs when executed inside or outside a function.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Executive Summary:

There are only two ways for R to know that an else clause belongs to the if clause above it:

  1. The entire if...else statement (and perhaps other statements as well) is enclosed in braces;
  2. The word else appears on the same line as the end of the if clause.

Evidence:

The above discussion helped me, but I hope I can offer a useful quibble. Yes, it is correct that

f <- function (exp)
    if (exp)
        1  
    else
        2

fails with the classic Error: unexpected 'else' in "else" message due to R's failure to keep reading past the 1. Two ways have been correctly offered to make R keep reading past the 1:

f <- function (exp) {
    if (exp)
        1  
    else
        2
}

and

f <- function (exp) if (exp) 1 else 2

But there is a third way not yet mentioned---just move else up a line. Thus, the following also works because R knows to keep reading past the 1:

f <- function (exp)
    if (exp)
        1  else
        2

I think the key point is to either brace the entire body of the function, or make sure the else occurs on the same line as the end of the if clause so that R knows to keep reading. That's why the one-line solution works. It is also why this works:

f <- function (exp)
    if (exp) {
        1
    } else
        2

But this fails:

f <- function (exp)
    if (exp) {
        1
    }  
    else
        2

And using the more standard bracing of the function body, this works too:

f <- function (exp) {
    if (exp) {
        1
    }  
    else
        2
}

But whether or not we are building a function is a red herring. What matters is only braces and location of else. Thus, these work:

{
    if (exp) {
        1
    }  
    else
        2
}


if (exp) {
    1
} else
    2

but this fails:

if (exp) {
    1
} 
else
    2

and to demonstrate my assertion 1 at the top, this works:

{
x <- 4
if (exp) 
    1
else
    2
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...