r语言 - if instead of else



我有一个简单的问题:我有两个函数。它们都使用

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语句在第一种情况下工作,而不是在第二种情况下!??

第二个例子不起作用,因为with的第一个参数应该是"一个环境,一个列表,一个数据帧,或一个整数,如sys.call "(参见参数部分?with)。

您可以通过将if语句包装在花括号中来避免"unexpected end of line"错误:

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))
}

您最好使用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

两个问题:首先,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时,这是有效的),但你最好使用switch代替,就像James建议的。


如果所有数据帧都一致命名,如示例中所示,那么有比使用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

三个expression都有可能执行。

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

在下面的例子中,只执行一个expression

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

最新更新