Rで複数のオブジェクトからリストを作るときに、オブジェクト名をリストの要素の名前にする

概要
Hmisc パッケージの llist() 函数を使うことで、リストを作るときに使ったオブジェクト名からリストの要素の名前をつけることができる。

やりたいこと

R言語では、あらかじめ複数個のオブジェクトを用意して、それらを1個のリストにまとめるということがよくある。以下の例では、animal, number, eraという3つのオブジェクトを作り、それらを unified という1個のリストにまとめている。

animal <- c("dog", "cat", "bear", "pig")
number <- c(24, 35, 12, 81, 33)
era <- c("Edo", "Heian", "Meiji")
unified <- list(animal, number, era)

こうやってできた unified の中身は以下の通りである。

[[1]]
[1] "dog"  "cat"  "bear" "pig" 

[[2]]
[1] 24 35 12 81 33

[[3]]
[1] "Edo"   "Heian" "Meiji"

元々のオブジェクト名にあった“animal”とか“number”といった文字列がなくなってしまっている。これだと、何を示しているものか分かりにくいので、できれば元々のオブジェクト名をリストの要素の名前にするようにしたい。

単純な方法としては、リストを作るときに明示的に名前を指定する方法がある。例えば、以下のようにする。

unified2 <- list(animal=animal, number=number, era=era)

こうすれば、名前が付いたリスト unified2 ができあがる。その中身は以下の通りである。

$`animal`
[1] "dog"  "cat"  "bear" "pig" 

$number
[1] 24 35 12 81 33

$era
[1] "Edo"   "Heian" "Meiji"

しかし、この方法は animal=animal のように、同じものを繰り返し入力しなくていけない点で面倒である

解法:Hmiscパッケージのllist()函数を使う

実は、Hmisc パッケージの llist() 函数を使えば、元々のオブジェクト名をリストの要素の名前にすることが簡単にできる。

unified3 <- Hmisc::llist(animal, number, era)

こうやってできた unified3 の中身は以下の通り。

$`animal`
animal 
[1] "dog"  "cat"  "bear" "pig" 

$number
number 
[1] 24 35 12 81 33

$era
era 
[1] "Edo"   "Heian" "Meiji"

ちなみに、元々のオブジェクト名とは別のものを名前にしたい箇所があれば、その部分だけ名前を明示的に指定すれば良い。以下の例では、era というオブジェクトに対応する箇所に“jidai”という名前をつけている。

unified4 <- Hmisc::llist(animal, number, jidai=era)

結果は以下の通り。

$`animal`
animal 
[1] "dog"  "cat"  "bear" "pig" 

$number
number 
[1] 24 35 12 81 33

$jidai
jidai 
[1] "Edo"   "Heian" "Meiji"

応用:複数の函数をリストにする場合の活用

複数の函数をリストにするときも、llist() 函数が活用できる。 例えば、数値ベクトル number2 に対し、その平均・中央値・標準偏差を一気に求めるとしよう。このとき、普通の list() 函数を使って函数のリストを作るとどうなるだろうか。

number2 <- c(58, 35, 11, 45, 57, 125, 83)
funs1 <- list(mean, median, sd)
lapply(funs1, function(f){f(number2)})

この函数のリスト funs1 には各要素に名前が付いていないため、最後の計算結果が以下のように分かりにくくなる。

[[1]]
[1] 59.14286

[[2]]
[1] 57

[[3]]
[1] 36.54417

これに対して、llist() 函数を使えば、リストに名前が付くので、最後の計算結果が分かりやすくなる。

funs2 <- Hmisc::llist(mean, median, sd)
lapply(funs2, function(f) f(number2))

結果は以下の通り。

$`mean`
[1] 59.14286

$median
[1] 57

$sd
[1] 36.54417