配列

配列 の R

1個の演習

配列について

Rのlistは、順序付けられた要素のコレクションです。vectorsとはいくつかの点で異なります。

  • 要素は異なる型にできます(たとえばnumericとcharacterを混ぜられます)。
  • 要素は複雑な構造にできます(ベクトル、他のリストなど)。
  • 要素にアクセスするための構文が少し異なります。

他の言語へのたとえは正確とは限りません。RのlistはPythonの辞書にいくらか似ていますが、listは順序付けられていて、数値インデックスでアクセスできます。Cのstructにもいくらか似ていますが、listは実行時に簡単に拡張できる点が異なります。

リストの作成

要素に名前(「タグ」と呼ばれることも多い)を付けるのは、ベクトルよりもリストでよく行われます。

list(x = 5.3, y = 4.2, color = "blue")
#> $x
#> [1] 5.3

#> $y
#> [1] 4.2

#> $color
#> [1] "blue"

ただし、タグは省略可能で、その場合Rは単にインデックス番号を使います。

list(5.3, 4.2, "blue")
#> [[1]]
#> [1] 5.3

#> [[2]]
#> [1] 4.2

#> [[3]]
#> [1] "blue"

リストの要素へのアクセス

方法は3つあり、それぞれ異なる場面で役立ちます。

1. $tag記法を使う

タグ名が前もってわかっている場合によく使われます。

point <- list(x = 5.3, y = 4.2, color = "blue")
#> point$x
#> [1] 5.3
#> point$color
#> [1] "blue"

2. [[tag]]記法を使う

タグ名を実行時に選べるという利点があります。角括弧([[ ]])が2重になっている点に注意してください。

want <- "y"
point[[want]] # same as point$y
#> [1] 4.2

3. 位置インデックスを使う

タグの有無にかかわらず使えます。ここでも角括弧は2重です。

point[[3]] # same as point$color
#> [1] "blue"

要素の追加と削除

簡単です。要素に代入すると、すでに存在すれば変更され、新しい場合は挿入されます。

point$color <- "red"
point$trust <- TRUE

# str() gives more compact output than the default display
str(point) 
#> List of 4
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"
#>  $ trust: logi TRUE

削除するには、不要な要素にNULLを代入します。

point$trust <- NULL
str(point)  
#> List of 3
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"

リストは「再帰的ベクトル」

vectorクラスは、技術的にはatomic vectorとして知られています。numeric、character、booleanなどのアトミックな値しか保持できないからです。listは他のリストを含むことができるため、recursive vectorとも呼ばれます。

これは単に専門用語の問題であるだけでなく、リストが任意に複雑な構造を持ちうることを思い出させてくれます。リストの要素にアクセスしたときに何が返されるかを理解するのは、プログラマーの責任です。

リストのインデックスについての補足

上の例のいくつかでは、リストの要素にアクセスするために二重の角括弧[[ ]]を使いました。これは要素を基になる型に平坦化しようとします。数値や文字列だけがほしい場合には便利です。

角括弧が1つの[ ]を使ってもこの平坦化は行われず、返される値はサブリストになります。

point[["color"]]
#> [1] "red"  # flattened

point["color"]
#> $color
#> [1] "red"  # sublist

サブリストがRの初心者プログラマーの望むものではないとしても、このことを知っておいてください。最大限の柔軟性のために、標準的なRの関数の多くは、ここでのように単一のアトミックな値を含む場合でもlistを返します。

ベクトルに変換するには2つの方法があります。

  1. [[1]]で最初の要素を取り出す
  2. unlist()関数を使う
pt <-point["color"]

pt[[1]]
#> [1] "red" # simple 1-element vector

unlist(pt)
#> color 
#> "red"  # 1-element vector with name

unlist()には注意してください。構造を平坦化するのはこのような単純な場合は便利ですが、より複雑なリスト要素では思わぬ結果を招くことがあります。

Advanced

内部表現

listは、アトミックなvectorと同様に、連続した領域に格納されます。違いは、数値ベクトルと真偽値ベクトルは値を格納するのに対し、リストはメモリの別の場所にあるオブジェクトへの参照を格納する点です。

これを知っていることはRのユーザーにとってほとんど重要ではありませんが、Exercismのような多言語コミュニティでは、他の言語に慣れたプログラマーの役に立つかもしれません。

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

配列を学習する