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つあり、それぞれ異なる場面で役立ちます。
$tag記法を使うタグ名が前もってわかっている場合によく使われます。
point <- list(x = 5.3, y = 4.2, color = "blue")
#> point$x
#> [1] 5.3
#> point$color
#> [1] "blue"
[[tag]]記法を使うタグ名を実行時に選べるという利点があります。角括弧([[ ]])が2重になっている点に注意してください。
want <- "y"
point[[want]] # same as point$y
#> [1] 4.2
タグの有無にかかわらず使えます。ここでも角括弧は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]]で最初の要素を取り出すunlist()関数を使うpt <-point["color"]
pt[[1]]
#> [1] "red" # simple 1-element vector
unlist(pt)
#> color
#> "red" # 1-element vector with name
unlist()には注意してください。構造を平坦化するのはこのような単純な場合は便利ですが、より複雑なリスト要素では思わぬ結果を招くことがあります。
listは、アトミックなvectorと同様に、連続した領域に格納されます。違いは、数値ベクトルと真偽値ベクトルは値を格納するのに対し、リストはメモリの別の場所にあるオブジェクトへの参照を格納する点です。
これを知っていることはRのユーザーにとってほとんど重要ではありませんが、Exercismのような多言語コミュニティでは、他の言語に慣れたプログラマーの役に立つかもしれません。