если вместо других - PullRequest
       3

если вместо других

1 голос
/ 08 декабря 2011

У меня простой вопрос: у меня есть две функции. Они оба используют

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 ]

4 голосов
/ 08 декабря 2011

Второй пример не работает, потому что первый аргумент 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 голос
/ 08 декабря 2011

Две проблемы: во-первых, 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, первое условие удовлетворяется и возвращается 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 вместо этого, как предлагает Джеймс.


Если все ваши фреймы данныхЕсли имя будет последовательно названо, как в примере, то есть даже лучшее решение, чем использование 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
1 голос
/ 08 декабря 2011

Возможно, вам лучше использовать 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
0 голосов
/ 08 декабря 2011

возможно, что все три expression s будут выполнены.

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

В нижеприведенном случае будет выполняться только один expression.

if(...) {expression}  
else
{        
    if(...) {expression}        
    else 
    {
        expression
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...