リストの結合
次に、リストの結合について見ていきます。
2つ以上のリストを結合したいときは、次のように関数cの引数に結合したいリストを渡します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | > #リストの結合 > lstA <- list(1, 2, 3) > lstB <- list(4, 5) > > lstC <- c(lstA, lstB) > lstC [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 [[4]] [1] 4 [[5]] [1] 5 |
リストの並び替え・ソート
リストの並び替え及びソートの仕方について紹介します。
要素の取得と同様に、インデックスと名前でリストの要素を並び替える方法を解説します。
インデックスで指定
まずインデックスでリストの要素を並び替えを行っていきます。
並び替え後の要素に対応するようにインデックスのリストを大括弧に渡すことで、リストの要素を入れ替えることができます。
- 1番目を末尾に移動したいときは、lst <- lst[c(setdiff(seq_len(length(lst)), 1), 1)]
- 1から4番目を後ろに移動したいときは、lst <- lst[c(setdiff(seq_len(length(lst)), seq(1, 4)), seq(1, 4))]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | > #インデックスで並び替え > lst1 <- list(1, 2, 3, 4, 5) > lst1 <- lst1[c(setdiff(seq_len(length(lst1)), 1), 1)] #1番目の要素を末尾に移動 > lst1 [[1]] [1] 2 [[2]] [1] 3 [[3]] [1] 4 [[4]] [1] 5 [[5]] [1] 1 > > lst1 <- lst1[c(setdiff(seq_len(length(lst1)), seq(1, 4)), seq(1, 4))] #1から4番目を後ろに移動 > lst1 [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 [[4]] [1] 4 [[5]] [1] 5 |
また、リストをソートする場合は、次のように関数orderを使います。
関数orderによりリストの要素の順位を得ることができ、その順位(インデックス)を大括弧に入れることでリストをソートすることができます。
降順にしたいときは、関数orderの引数decreasingをTRUEにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | > #リストのソート > lst5 <- list(3, 6, 9, 1, 2, 8, 4, 5, 10, 7) > lst5[order(unlist(lst5))] #昇順 [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 [[4]] [1] 4 [[5]] [1] 5 [[6]] [1] 6 [[7]] [1] 7 [[8]] [1] 8 [[9]] [1] 9 [[10]] [1] 10 > lst5[order(unlist(lst5), decreasing = TRUE)] #降順 [[1]] [1] 10 [[2]] [1] 9 [[3]] [1] 8 [[4]] [1] 7 [[5]] [1] 6 [[6]] [1] 5 [[7]] [1] 4 [[8]] [1] 3 [[9]] [1] 2 [[10]] [1] 1 |
リストを逆順にしたい場合は、次のように関数revを使います。
要素の並び替えの時と同じように、seq_lenによって得られるリストの長さの数列を関数revで逆順にすることで、リストの長さまでの逆順のインデックスが得られるので、リストを逆にすることができます。
また、関数revで直接リストを逆順に並び替えることもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | > lst5[rev(seq_len(length(lst5)))] #逆順 [[1]] [1] 7 [[2]] [1] 10 [[3]] [1] 5 [[4]] [1] 4 [[5]] [1] 8 [[6]] [1] 2 [[7]] [1] 1 [[8]] [1] 9 [[9]] [1] 6 [[10]] [1] 3 > > rev(lst5) [[1]] [1] 7 [[2]] [1] 10 [[3]] [1] 5 [[4]] [1] 4 [[5]] [1] 8 [[6]] [1] 2 [[7]] [1] 1 [[8]] [1] 9 [[9]] [1] 6 [[10]] [1] 3 |
名前で指定
リストに名前がある場合、名前でリストの要素を並び替えることもできます。
インデックスのときと同様に、並び替え後の要素に対応するように名前のベクトルをリストの大括弧に渡すことで、並び替えをすることができます。
- 名前"a"の要素を末尾に移動したいときは、lst <- lst[c(setdiff(names(lst), "a"), "a")]
- 名前"b"と"c"の要素を後ろに移動したいときは、lst <- lst[c(setdiff(names(lst), c("b", "c")), c("b", "c"))]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | > #名前で並び替え > lst1 <- list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5) > lst1 <- lst1[c(setdiff(names(lst1), "a"), "a")] #名前"a"の要素を末尾に移動 > lst1 $b [1] 2 $c [1] 3 $d [1] 4 $e [1] 5 $a [1] 1 > > lst1 <- lst1[c(setdiff(names(lst1), c("b", "c")), c("b", "c"))] #名前"b"と"c"の要素を末尾に移動 > lst1 $d [1] 4 $e [1] 5 $a [1] 1 $b [1] 2 $c [1] 3 |
欠測値の処理
次に、リストの欠測値の処理の方法について見ていきます。
ベクトルやデータフレームの時のように関数na.omitを使って欠測値NAを除去することができません。
次のようにリスト用の欠測値を除去する関数を定義する必要があります。
1 2 3 4 | na.omit.list <- function(lst) { lst_naOmitted <- lapply(lst, na.omit) return(lst_naOmitted[sapply(lst_naOmitted, function(x) {length(x) != 0})]) } |
上の関数na.omit.listを用いることで、任意の要素を持つリスト中の欠測値を除去することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | > lst6 <- list(3, NA, 1, 6, NA, 4) > na.omit.list(lst6) [[1]] [1] 3 [[2]] [1] 1 [[3]] [1] 6 [[4]] [1] 4 > > lst7 <- list(c(1, 2, NA), c(4, NA), data.frame(col1 = c(1, 2), col2 = c(NA, 4))) > na.omit.list(lst7) [[1]] [1] 1 2 attr(,"na.action") [1] 3 attr(,"class") [1] "omit" [[2]] [1] 4 attr(,"na.action") [1] 2 attr(,"class") [1] "omit" [[3]] col1 col2 2 2 4 |
リストのベクトル・データフレームへの変換
リストをベクトルとデータフレームに変換する方法を紹介します。
関数unlstを用いることでリストをベクトルに変換することができます。
リスト中に異なる型(Type)がある場合、変換後に型が変更される点に注意が必要です。
逆にベクトルからリストに変換するときは、関数as.listを使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | > #ベクトルへに関する変換 > lst4 <- list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) > vector_lst4 <- unlist(lst4) #リストからベクトルへの変換 > vector_lst4 [1] 1 2 3 4 5 6 7 8 9 10 > > vec4 <- c(1, 2, 3, 4, 5) > lst_vec4 <- as.list(vec4) #ベクトルからリストへの変換 > lst_vec4 [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 [[4]] [1] 4 [[5]] [1] 5 |
データフレームに変換する際は、関数as.data.frameを使います。 変換したいリストを関数の引数に渡すことで、データフレームに変換することができます。
ベクトルの時と同様に、関数as.listでデータフレームからリストに変換できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | > #データフレームに関する変換 > lst4 <- list("numbers" = seq_len(10), "letters" = letters[seq_len(10)]) > dataFrame_lst4 <- as.data.frame(lst4) #リストからデータフレームへの変換 > dataFrame_lst4 numbers letters 1 1 a 2 2 b 3 3 c 4 4 d 5 5 e 6 6 f 7 7 g 8 8 h 9 9 i 10 10 j > > dataFrame4 <- data.frame("numbers" = seq_len(10), "letters" = letters[seq_len(10)]) > lst_dataFrame4 <- as.list(dataFrame4) #データフレームからリストへの変換 > lst_dataFrame4 $numbers [1] 1 2 3 4 5 6 7 8 9 10 $letters [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" |
リストの演算
リストの演算について見ていきます。
リストには算術演算を適用できないため、一度ベクトルに変換した後に演算を行う必要があります。
ベクトルと同様に、numeric型の要素を持つリストであれば次の演算が可能です。
和、差、積、商、べき乗、整数商、剰余、内積、テンソル積を計算することができます。
演算子 | 演算 |
+ | 和 |
- | 差 |
* | 積 |
/ | 商 |
^ | べき乗 |
%/% | 整数商 |
%% | 剰余 |
%*% | 内積 |
和、差、積、商の実行例は以下の通りです。他の算術演算子についても同様に計算できます。
まず、unlistでベクトルに変換した後に演算を行い、as.listでベクトルに戻すと演算後のリストを得ることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | > #リストの演算 > lst_num1 <- list(1, 2, 3, 4, 5) > lst_num2 <- list(2, 3, 4, 5, 6) > > #和 > as.list(unlist(lst_num1) + 1) [[1]] [1] 2 [[2]] [1] 3 [[3]] [1] 4 [[4]] [1] 5 [[5]] [1] 6 > as.list(unlist(lst_num1) + unlist(lst_num2)) [[1]] [1] 3 [[2]] [1] 5 [[3]] [1] 7 [[4]] [1] 9 [[5]] [1] 11 > > #差 > as.list(unlist(lst_num1) - 1) [[1]] [1] 0 [[2]] [1] 1 [[3]] [1] 2 [[4]] [1] 3 [[5]] [1] 4 > as.list(unlist(lst_num1) - unlist(lst_num2)) [[1]] [1] -1 [[2]] [1] -1 [[3]] [1] -1 [[4]] [1] -1 [[5]] [1] -1 > > #積 > as.list(unlist(lst_num1) * 2) [[1]] [1] 2 [[2]] [1] 4 [[3]] [1] 6 [[4]] [1] 8 [[5]] [1] 10 > as.list(unlist(lst_num1) * unlist(lst_num2)) [[1]] [1] 2 [[2]] [1] 6 [[3]] [1] 12 [[4]] [1] 20 [[5]] [1] 30 > > #商 > as.list(unlist(lst_num1) / 2) [[1]] [1] 0.5 [[2]] [1] 1 [[3]] [1] 1.5 [[4]] [1] 2 [[5]] [1] 2.5 > as.list(unlist(lst_num1) / unlist(lst_num2)) [[1]] [1] 0.5 [[2]] [1] 0.6666667 [[3]] [1] 0.75 [[4]] [1] 0.8 [[5]] [1] 0.8333333 |
集合演算
リストの集合演算に関する関数を紹介します。
次の表の関数を用いることで、リストの和集合、差集合、積集合を計算することができます。
また、集合として等しいかどうか、集合の要素であるかどうかも計算することもできます。
関数 | 演算 |
union | 和集合 |
setdiff | 差集合 |
intersect | 積集合 |
setequal | 同じ集合かどうか |
is.element | 集合の要素であるかどうか |
実行例は以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | > #集合演算 > lst_num1 <- list(1, 2, 3, 4, 5) > lst_num2 <- list(4, 5, 6, 7) > lst_chr1 <- list("a", "b", "a", "c", "b") > lst_chr2 <- list("b", "c", "d", "e") > lst_chr3 <- list("a", "b", "c") > > #和 > union(lst_num1, lst_num2) [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 [[4]] [1] 4 [[5]] [1] 5 [[6]] [1] 6 [[7]] [1] 7 > union(lst_chr1, lst_chr2) [[1]] [1] "a" [[2]] [1] "b" [[3]] [1] "c" [[4]] [1] "d" [[5]] [1] "e" > > #差 > setdiff(lst_num1, lst_num2) [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 > setdiff(lst_chr1, lst_chr2) [[1]] [1] "a" > > #積 > intersect(lst_num1, lst_num2) [[1]] [1] 4 [[2]] [1] 5 > intersect(lst_chr1, lst_chr2) [[1]] [1] "b" [[2]] [1] "c" > > #集合として等しいか > setequal(lst_num1, lst_num2) [1] FALSE > setequal(lst_chr1, lst_chr3) [1] TRUE > > #集合の要素か > is.element(lst_num1, 1) [1] TRUE FALSE FALSE FALSE FALSE > is.element(lst_chr1, "a") [1] TRUE FALSE TRUE FALSE FALSE |
合計・平均・分散
リストの合計、平均、分散を計算する例を紹介します。
リストについてもsumやmean、varを適用することができないので、ベクトルに変換してから計算する必要があります。
合計、平均、分散の計算例は以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | > #合計・平均・分散 > lst8 <- list(200, 220, 180, 190, 200, 210) > > sum(unlist(lst8)) #合計 [1] 1200 > mean(unlist(lst8)) #平均 [1] 200 > var(unlist(lst8)) #分散 [1] 200 > > lst9 <- list(A = c(290, 300, 270, 320, 330, 350), + B = c(100, 130, 200, 210, 150, 140), + C = c(300, 50, 350, 550, 140, 200)) > > lapply(lst9, sum) #合計 $A [1] 1860 $B [1] 930 $C [1] 1590 > lapply(lst9, mean) #平均 $A [1] 310 $B [1] 155 $C [1] 265 > lapply(lst9, var) #分散 $A [1] 840 $B [1] 1790 $C [1] 31150 |
リストのファイルへの保存
最後にリストをtxtファイルやcsvファイルに保存する例を紹介します。
関数write.tableやwrite.csvでtxtファイルやcsvファイルにリストの要素を出力することができます。
様々なリストの出力結果を以下にまとめました。
次のようにリストの要素が1つのみから構成される場合、txtファイルとcsvファイルへの出力結果は下図のようになります。
1 2 3 4 | lst1 <- list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) write.table(lst1, "リストの操作1.txt", quote = FALSE) #txtファイル write.csv(lst1, "リストの操作1.csv") #csvファイル |
リストにベクトルが含まれている場合、txtファイルやcsvファイルに出力するとデータフレームの時と同じような出力になります。
1 2 3 4 | lst4 <- list("numbers" = seq_len(10), "letters" = letters[seq_len(10)]) write.table(lst4, "リストの操作2.txt", quote = FALSE) #txtファイル write.csv(lst4, "リストの操作2.csv") #csvファイル |
まとめ
R言語のリストの操作方法について見ていきました。
データフレームやベクトルと同様に、インデックス、名前、真偽値による操作方法があります。
ベクトルの操作方法との違いとして、リストの後ろに付ける大括弧の数です。
リストの要素を取得するには2重の大括弧をつける必要があります。
1重の大括弧をつけても取得は可能ですが、戻り値はリストとなるため注意が必要です。
また、ベクトルと違い様々な型を1つのリストに格納することができるため、より柔軟なデータを作ることが可能です。