library(knitr) opts_knit$set(base.dir='./', fig.path='', out.format='md') opts_chunk$set(prompt=FALSE, comment='', results='markup')
rlistはlistオブジェクトを操作するためのツール群です。このライブラリの目標は、listの中に格納されている表形式(data.frame)ではないデータを操作するための、幅広い関数をユーザに提供することで、listを操作しやすくすることです。
このパッケージは、listに対するマップ, フィルタリング、グルーピング、ソート、更新、検索、ファイル入出力などの数多くの関数を提供するものです。このパッケージにおける大半の関数は、listに対するデータ処理において、チェーン(連鎖)操作できるように、"パイプ・フレンドリー"な設計となっています。
rlistの完璧なガイドとしては、rlist Tutorialを強くお勧めします。
最新版をGithubからインストールする:
devtools::install_github("renkun-ken/rlist")
CRANからインストールする:
install.packages("rlist")
Rにおいては、data.frameに代表されるような表形式で格納されている構造化されたデータを扱うための強力なツールがたくさんあります。しかし、ある種のデータは非表形式であり、例えば異なるDBなどのレコードが異なる属性(列)を持っているようなケースがあり、それぞれの属性(列)が異なる数値を格納しているようなケースも考えられます。
このような形式のデータをdata.frameに格納するのは難しいことではある一方、Rにおいてはlist
オブジェクトは、このようなレコードの違い、あるいは多様性といったものを表現するために十分フレキシブルな構造を持っています。rlistはlist
オブジェクトにため込まれた非構造データを処理するためのツールボックスであり、listに対するパイプ・フレンドリーな多数の高階関数を提供するものです。
まず、私たちが、名前・年齢・趣味(複数)・使用するプログラミング言語、およびその使用年数を持つ"開発者"のリストを持っているとしましょう。
library(rlist) devs <- list( p1=list(name="Ken",age=24, interest=c("reading","music","movies"), lang=list(r=2,csharp=4)), p2=list(name="James",age=25, interest=c("sports","music"), lang=list(r=3,java=2,cpp=5)), p3=list(name="Penny",age=24, interest=c("movies","reading"), lang=list(r=1,cpp=4,python=2)))
これはデータフレームの形とは合わないので、データのタイプとしては、関係データベースの用語でいうところの非リレーショナルなものです。しかし、JSONやYAMLのデータ形式としては、容易に格納される形ではあります。Rにおいては、listオブジェクトは、このような幅広い非リレーショナルなデータを表現するための十分な柔軟性があります。このパッケージは、この手のデータに対する問い合わせ(Queryの発行)や操作ための幅広い関数を提供します。
次で示す例においては、出力のデータ構造を示すために、str()
を使います。
音楽が好きで3年以上のRの経験がある開発者をフィルタリングして抽出してみましょう。
str( list.filter(devs, "music" %in% interest & lang$r >= 3) )
彼らの名前・年齢だけを選択してみましょう。
str( list.select(devs, name, age) )
開発者のリストデータを、趣味の数のデータへとmap(変換)してみましょう。
str( list.map(devs, length(interest)) )
これらの基本的な関数に加えて、rlistはグルーピング・結合・検索・ソート・更新などの様々な関数もサポートしています。その他の機能については、rlist Tutorialを読んでください。
このパッケージにおいて、ほとんどすべての関数は、次に示すラムダ式の形式を使用することができます:
expression
x ~ expression
f(x) ~ expression
f(x,i) ~ expression
f(x,i,name) ~ expression
ここで、x
はリストの要素を表し、i
はリストのインデックス、name
はリストの要素の名前を表します. もし、x, i, name
といったシンボルが明示的に与えられなかった場合、.
、.i
、.name
がそれぞれのデフォルトのオブジェクトとして使われます。
nums <- list(a=c(1,2,3),b=c(2,3,4),c=c(3,4,5)) list.map(nums, c(min=min(.),max=max(.))) list.filter(nums, x ~ mean(x)>=3) list.map(nums, f(x,i) ~ sum(x,i))
音楽が好きでRを使う開発者の名前を問い合わせ、その結果をdata.frameとして出力してみましょう。
devs |> list.filter("music" %in% interest & "r" %in% names(lang)) |> list.select(name, age) |> list.stack()
上記の例では、R4.1で導入されたパイプ構文 |>
を使用して、コマンドを流暢なスタイルでチェーンします。
List()
関数はほとんど全てのlist関数が定義された環境とデータであるlistを1つにまとめあげるものです。先ほどの例をList環境を用いて書いたものが以下になります。
ldevs <- List(devs) ldevs$filter("music" %in% interest & "r" %in% names(lang))$ select(name,age)$ stack()$ data
このパッケージはMIT Licenseの下で公開されています。
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.