如果不是别的

时间:2011-12-08 11:00:29

标签: r if-statement

我有一个简单的问题:我有两个功能。他们都使用

if(...) {expression}
if(...) {expression}
if(...) {expression}

而不是

if(...) {expression}
else{
      if(...) {expression}
      else {expression}
}

但只有两者之一。

第一个完美无缺:

test.1 <- function (y) {
 if(y == 1){z <- 10}
 if(y == 2){z <- 20}
 if(y == 5){z <- 50}

 return(z)
}

第二个不起作用:

df.1 <- data.frame(A = 1:3)
df.2 <- data.frame(A = 4:6)
df.3 <- data.frame(A = 7:9)

 test.2 <- function (num) {
  x <- with(if(num == 1){df.1} 
            if(num == 2){df.2}
            if(num == 3){df.3}, {sum(A)})
return(x)
}

我需要使用if else表达式才能使第二个函数起作用:

test.2 <- function (num) {
  x <- with(if(num == 1){df.1} 
            else {if(num == 2){df.2}
                  else {df.3}
                  }, {sum(A)})
  return(x)
}

我真的不明白为什么这个多个if语句在第一种情况下起作用而在第二种情况下不起作用!??

4 个答案:

答案 0 :(得分:4)

第二个例子不起作用,因为with的第一个参数应该是“sys.call中的环境,列表,数据框或整数”(参见参数)第?with}节。

通过将if语句包装在大括号中,可以避免“意外的行结束”错误:

test.2 <- function (num) {
  x <- with({if(num == 1)df.1 
             if(num == 2)df.2
             if(num == 3)df.3}, {sum(A)})
  return(x)
}

但是这仍然不起作用,因为括号内有3个表达式,只返回最后一个计算表达式。好吧,如果num==3它会起作用......但我们可以做得更好。您可以在此使用switch

test.2 <- function (num) {
  with(switch(num, df.1, df.2, df.3), sum(A))
}

答案 1 :(得分:1)

您最好使用switch

test.2 <- function(num){
 x <- with(switch(num,df.1,df.2,df.3),{sum(A)})
 return(x)
}


test.2(1)
[1] 6
test.2(2)
[1] 15
test.2(3)
[1] 24

答案 2 :(得分:1)

两个问题:首先,with期望在其第一个参数中使用单个表达式(这可以告诉data.frame或环境)。您可以通过将这些if语句包装在花括号中来使其成为单个表达式来解决此问题。

test.2 <- function (num) {
  x <- with(
    {
      if(num == 1){df.1} 
      if(num == 2){df.2}
      if(num == 3){df.3}
    }, 
    sum(A)
  )
  return(x)
}

第二个问题是,在找到匹配项后,您没有从表达式返回。因此,当num为1时,将满足第一个if条件并返回df.1。但是,下一个if表达式被评估,并且由于num不是2,因此返回NULL。同样,第三个if表达式返回NULL。因为那是块中的最后一个表达式,所以返回的是。你实际上有

with(NULL, sum(A))

与简单sum(A)相同,因为A不存在而引发错误。

你可以再做一次像

这样的修复
test.2 <- function (num) {
  x <- with(
    {
      if(num == 1)return(df.1) 
      if(num == 2)return(df.2)
      if(num == 3)return(df.3)
    }, 
    sum(A)
  )
  return(x)
}

(这在num为1,2或3时有效),但与James建议相比,使用switch要好得多。


如果所有数据框都一致地命名,如示例中所示,那么比使用switch更好的解决方案。使用paste获取变量名称,然后调用get

test.3 <- function(num) with(get(paste("df", num, sep = ".")), sum(A))
test.3(1) #6
test.3(2) #15
test.3(3) #24

答案 3 :(得分:0)

所有三个expression都可能执行。

if(...) {expression} 
if(...) {expression} 
if(...) {expression} 

在下面的情况下,只会执行一个expression

if(...) {expression}  
else
{        
    if(...) {expression}        
    else 
    {
        expression
    }
}