2011-12-08 22 views
1

私は簡単な質問があります:私は2つの機能を持っています。どちらももしそうでなければ

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

代わりの

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

しかし、両方の作品を1つだけ使用します。

最初のものは完璧に動作します:

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

return(z) 
} 

秒1は動作しません:

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

私は第二の機能の仕事を得るためにあれば、他の表現を使用する必要があります。

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文が最初のケースで動作するのですが、t彼は第二のもの!

+0

あなたは、x < - の部分を使ってifを取りましたか? ifは、x < - withの部分で使用する変数を設定しますか? –

+0

はい私はすでにそれを試しました。それは動作しますが、実際のコードではwith(...)部分に200行のコードがあります。つまり、このようにすれば、200行ではなく600行のコードが得られます。 ()内の適切な場所に。 –

+0

基本的な問題は、2番目の関数が正しいR構文に似ていないということです。あなたが本質的に 'ith(num == 1){df.1} if(num == 2){df.2} if(num == 3){df.3}、{sum A)}) 'つまり、with()への2つの引数です。このコンテキストではガベージだけです。代わりに 'switch'を使用してください。とにかく値を返すようには設計されていないので、{}内のdata.framesは、私が考えることができる限り、 'x'に割り当てられるのではなく、印刷されます。 –

答えて

4

withへの最初の引数は、「環境、リスト、データフレーム、ことになっているため、2番目の例では動作しません。またはsys.callのような整数です(引数セクション?withを参照してください)。

あなたがラップすることにより、エラー「行の予期せぬ終了」を避けることができれば、中括弧内の文:

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

3つすべてexpressionが実行可能です。

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

以下の場合、expressionが実行されます。

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

一般的に、あなたはリジッドです。しかしこれは問題ではありません。上記(test.2)に掲載したコードを実行しようとすると、Rに "予期しない行末"のようなエラーが発生することがわかります。 –

+0

ああ、それはRです。それは私の紅茶ではありません。 – Azodious

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 
1

2つの問題:まず、withは、最初の引数に(つまり、data.frameや環境へのevaulates)単一の式を期待しています。それらを単一の式にするために、中括弧でそれらの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が返されます。同様に、式はNULLを返します。これがブロック内の最後の式なので、それが返されます。あなたは効果的Aが存在しないため、エラーがスローされます単にsum(A)、同じである

with(NULL, sum(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 
関連する問題