トラック
/
R
R
/
シラバス
/
ベクトルのフィルタリング
ベク

ベクトルのフィルタリング の R

3個の演習

ベクトルのフィルタリングについて

Vectorsの概念で見たように、ベクトルは条件式の中で使うことができ、真偽値のベクトルが得られます。 これはさらに、all()やany()といった関数でも使うことができます。

v <- c(4, 7, 10)
v >= 6
#> [1] FALSE  TRUE  TRUE
all(v > 6)
#> [1] FALSE    # not all elements match this condition
any(v > 6)
#> [1] TRUE     # at least one element matches

このテクニックは、ここで見たものよりはるかに強力です。

ベクトルの部分集合

ベクトルから特定の要素を取り出すには、インデックス番号か、インデックスのベクトルを使います。

v <- 5:10
v
#> [1]  5  6  7  8  9 10
v[3] 
#> [1] 7
v[c(2, 4)]
#> [1] 6 8

別の方法として、論理値のベクトルを使って元のベクトルを絞り込み、TRUEに対応する要素の部分集合を返すこともできます。

v <- 1:3
bools <- c(FALSE, TRUE, TRUE)
v[bools]
#> [1] 2 3

そこから、条件式で真偽値のベクトルを生成するまで、あと一歩です。

bools <- v >= 2
bools
#> [1] FALSE  TRUE  TRUE

v[bools]
#> [1] 2 3

# simpler form
v[v >= 2]
#> [1] 2 3

これらの条件式は、複数のベクトルや関数を組み合わせて、いくらでも複雑にできます。

v <- 1:10
w <- 10:1

# pairwise comparison
v > w
#> [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

# shorter form
v[v > w]
#> [1]  6  7  8  9 10

名称について

この概念を「Vector Filtering」と名付けました。できるだけ多くのプログラマーに意味が通じることを願ってのことです。

Rコミュニティの中では、「Subsetting」という言葉のほうがよく使われるでしょう。

リサイクル

話を簡単にするため、上の例ではどれも同じ長さのベクトルを比較しました。 長さが合わなかったらどうなるのでしょうか?

その答えは、意図して使えば強力ですが、予期していないと混乱を招くものです。

例を見てみましょう。

v <- 1:6
cond <- c(TRUE, FALSE)
v[cond]
#> [1] 1 3 5

何が起きたのでしょうか? 長さ6のベクトルを、長さ2の真偽値でインデックス指定しましたが、結果は長さ3のベクトルになりました。

式の中で使うにはベクトルが「短すぎる」とき、Rは目的の長さに達するまでそのベクトルを繰り返します。これが「リサイクル」です。 これにより、c(TRUE, FALSE)というベクトルはc(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE)になり、v[cond]はvのうちTRUEに対応する値、この場合は奇数を返しました。

では、次の例では何が起きているのでしょうか?

v <- 1:3
0.5 * v
#> [1] 0.5 1.0 1.5
2 + v
#> [1] 3 4 5

一見するとスカラー倍と、(少し変わった)スカラー加算のように見えますが、Rにスカラーはありません。

代わりに、数値がリサイクルされてvと同じ長さのベクトルになり、c(0.5, 0.5, 0.5)やc(2, 2, 2)を使って要素ごとに演算が適用されます。

Caution

リサイクルはとてもとても便利ですが、本当にそれが意図した動作か確認しましょう。

ベクトルの長さが少しでも食い違うと(たとえば99と100)、混乱を招くバグの原因になります。

リサイクルは、どちらかのベクトルの長さが1のときだけ使うことを勧める人もいます。

インデックスを見つける

which()関数は真偽値の引数を取り、TRUEになるインデックスのベクトルを返します。

v
#> [1] 2 7 9

v[v > 5]  # returns values
#> [1]  7  9

which(v > 5) # returns indices
#> [1] 2 3

要素が存在するか確認する

ここまでの節では、ある条件に合う要素を見つける方法を扱ってきました。 特定の要素がベクトルに含まれているかどうかだけを知りたいときは、%in%演算子を使います。

3 %in% 1:5
#> [1] TRUE
7 %in% 1:5
#> [1] FALSE

これは次のコードと機能的には同じですが、ずっと便利です。

length(v[v == 3]) > 0
#> [1] TRUE

%notin%演算子というものもあり、%in%の論理notを返します。

GitHubで編集 リンクは新しいウィンドウまたはタブで開きます

ベクトルのフィルタリングを学習する

練習はロックされています

ベクトルのフィルタリングを練習するには、あと2個の演習のロックを解除してください