web-dev-qa-db-ja.com

Rのifelseステートメントがベクトルを返せないのはなぜですか?

Rのifelseステートメントは時々非常に便利であることがわかりました。例えば:

ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2

しかし、私は次の動作に多少混乱しています。

ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3

これは私の給与よりも高い設計上の選択ですか?

102

ifelse状態のドキュメント:

ifelseは、testと同じ形状の値を返します。この変数には、yesの要素がnoであるか、testであるかによって、TRUEまたはFALSEから選択された要素が入ります。

長さ1のテスト値を渡すため、長さ1の結果が得られます。より長いテストベクトルを渡すと、結果が長くなります。

_> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4
_

したがって、ifelseは、ブール値のベクトルをテストし、(ベクトル)yesおよびno引数から取得した要素で満たされた同じ長さのベクトルを返すという特定の目的を目的としています。

関数の名前のために、通常のif () {} else {}構造だけが必要な場合にこれを使用することはよくある混乱です。

83
Nathan Kitchen

ifの代わりに単純なifelseステートメントが必要だと思います-Rでは、ifは単なる制御フロー構造ではなく、値を返すことができます。

> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4
61
Ken Williams

ifelse内で結果を割り当てると、問題を回避できることに注意してください。

ifelse(TRUE, a <- c(1,2), a <- c(3,4))
a
# [1] 1 2

ifelse(FALSE, a <- c(1,2), a <- c(3,4))
a
# [1] 3 4
11
Cath

ええ、ifelse()はテストの大きな長いベクトルがあり、それぞれを2つのオプションのいずれかにマッピングしたい場合に本当に設計されていると思います。たとえば、私はよくplot()の色を次のようにします:

_plot(x,y, col = ifelse(x>2,  'red', 'blue'))
_

テストの大きな長いベクトルがあり、出力のペアが必要な場合は、sapply()またはplyrllply()または何かを使用できます。

9
Brendan OConnor

Cathによって提案されたアプローチに似たアプローチを次に示しますが、既存の事前に割り当てられたベクトルで機能します

次のようなget()の使用に基づいています。

a <- c(1,2)
b <- c(3,4)
get(ifelse(TRUE, "a", "b"))
# [1] 1 2
4
bmonger

ユーザーがswitchの代わりにifelseステートメントのみを必要とする場合があります。その場合:

condition <- TRUE
switch(2-condition, c(1, 2), c(3, 4))
#### [1] 1 2

(Ken Williamsの答えの別の構文オプションです)

3
agenis

`if`を使用します。

> `if`(T,1:3,2:4)
[1] 1 2 3
1
blueskyddd

あなたの場合、dplyrからif_elseを使用すると役に立ちます。if_elseifelseよりも厳密であり、ケースに対してエラーをスローします。

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2
0
Matifou