本文へスキップ
からだにいいもの

Rのトピックスを中心に『まだ、まだ、知らない、役に立つ情報?』を発信します。

Rで解析:データ構造を図で理解する「paintr」パッケージ

Rでデータを扱う際は、ベクトルや行列、データフレーム、リスト、配列といった構造の違いを理解しておくことが重要です。しかし、入れ子になったデータ構造の把握や、ブジェクトと値の関係は、コンソールの出力から理解するのは大変です。

 本パッケージは、そんな課題を解決することが可能です。例えばベクトル、行列、データフレーム、リスト、配列の値を簡単に把握可能です。

パッケージバージョンは0.0.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。

パッケージのインストール

下記コマンドを実行してください。

# パッケージのインストール
install.packages("paintr")

# パッケージの読み込み
library("paintr")
スポンサーリンク

コマンド例

詳細はコメント、パッケージのヘルプを確認してください。

紹介では、以下の地域の健康教室で記録した歩数と身体測定の値を例に、各コマンドの動作を確認します。

# 参加者5名の1日あたり平均歩数;名前付きベクトル
steps <- c(佐藤 = 8420, 鈴木 = 6180, 高橋 = 10250, 田中 = 7530, 伊藤 = 5940)

# 参加者1名の4週間の記録;週×測定項目の行列
sokutei <- matrix(
  c(8420, 8890, 9130, 9560,
    62.4, 62.1, 61.8, 61.5,
    132, 130, 128, 127),
  nrow = 4,
  dimnames = list(
    c("1週", "2週", "3週", "4週"),
    c("歩数", "体重", "血圧")))

# 参加者名簿;列ごとに型が異なるデータフレーム
sanka <- data.frame(
  氏名 = c("佐藤", "鈴木", "高橋", "田中", "伊藤"),
  年代 = c(60L, 50L, 70L, 60L, 50L),
  歩数 = c(8420, 6180, 10250, 7530, 5940),
  達成 = c(TRUE, FALSE, TRUE, FALSE, FALSE))

# 会場ごとの参加人数に対する歩数;長さの異なるリスト
kaijo <- list(
  中央 = c(8420, 6180, 10250),
  東部 = c(7530, 5940),
  西部 = c(9110, 8760, 7420, 6890))

# 週×会場×年の平均歩数;3次元配列
hosuu <- array(
  c(8420, 8890, 9130, 9560,
    7810, 8020, 8340, 8610,
    9050, 9280, 9440, 9770,
    8630, 9010, 9380, 9720,
    8050, 8330, 8590, 8880,
    9260, 9510, 9680, 9930),
  dim = c(4, 3, 2),
  dimnames = list(
    c("1週", "2週", "3週", "4週"),
    c("中央", "東部", "西部"),
    c("前年", "本年")))

ベクトルデータの可視化:paint_vectorコマンド

ベクトルの中身と各要素の添字を図として描画します。「ggplot2」パッケージでプロットする場合はgpaint_vectorコマンドを使用します。

オプション意味初期値
datavectorクラスを持つオブジェクト、因子や日付などクラス付きの原子ベクトルも指定可なし
layoutベクトルを並べる向き“vertical”(候補: “vertical”, “horizontal”)
show_indices添字の表示位置、ベクトルの添字は1種類のため排他選択“none”(候補: “none”, “inside”, “outside”)
highlight_area塗り分けるセルを示す、データと同じ長さの論理ベクトルNULL
highlight_colorセルの背景を塗る色“lemonchiffon”
graph_title図の左上に表示するタイトルpaste0(“Data Object: “, deparse(substitute(data)))
graph_subtitleタイトルの直下に表示する副題、NULLは長さとクラスを自動表示、NAまたは””は非表示NULL
sigfig黒色で描画する有効数字の桁数、1から15の範囲で指定3L
subtle_digits灰色で描画する桁の判定方法“insignificant”(候補: “insignificant”, “rounded”, “none”)
max_chars文字列を省略記号で切り詰める文字数の上限12L
max_rows縦並びのときに中間を省略する要素数の上限20L
max_cols横並びのときに中間を省略する要素数の上限15L
show_all文字が小さくなっても全てのセルを描画するかの指定FALSE
fontsizeフォントサイズ(ポイント)、NULLはデバイスに合わせて自動調整NULL
familyフォントファミリー“mono”
palette配色、”mint”、”slate”、”warm”、”classic”または色の名前付きリストを指定NULL
show_namesベクトルのnames()を描画するかの指定TRUE
max_name_chars名前を切り詰める文字数の上限、横並びのときのみ適用8L
highlight_locations塗り分ける要素の位置、highlight_areaの簡易指定NULL
# 名前付きベクトルを縦並びでプロット
paint_vector(steps)

# 横並びに変更し、添字をセルの外側にプロット
paint_vector(steps, layout = "horizontal", show_indices = "outside")

# 目標の8000歩に届かなかった参加者の位置を取得
under <- which(steps < 8000)
# 未達の参加者のセルのみ色を変えてプロット
paint_vector(steps, show_indices = "inside", highlight_locations = under,
             highlight_color = "mistyrose")

# タイトルと副題を日本語の任意の文字列に差し替えプロット
paint_vector(steps, graph_title = "参加者別の1日平均歩数",
             graph_subtitle = "健康教室:5名分")

# ggplot2でプロット
gpaint_vector(steps, layout = "horizontal", show_indices = "outside")

・名前付きベクトルを縦並びでプロット

・横並びに変更し、添字をセルの外側にプロット

・未達の参加者のセルのみ色を変えてプロット

・タイトルと副題を日本語の任意の文字列に差し替えプロット

・ggplot2でプロット

行列データの可視化:paint_matrixコマンド

行列の中身を、行名・列名・添字とともにプロットします。ggplot2でプロットする場合はgpaint_matrixコマンドを使用します。

オプション意味初期値
datamatrixクラスを持つオブジェクトなし
show_indices描画する添字の種類、”none”、”cell”、”row”、”column”、”all”から複数指定可“none”
highlight_area塗り分けるセルを示す、データと同じ形の論理行列NULL
highlight_colorセルの背景を塗る色“lemonchiffon”
graph_title図の左上に表示するタイトルpaste0(“Data Object: “, deparse(substitute(data)))
graph_subtitleタイトルの直下に表示する副題、NULLは次元とクラスを自動表示、NAまたは””は非表示NULL
sigfig黒色で描画する有効数字の桁数、1から15の範囲で指定3L
subtle_digits灰色で描画する桁の判定方法“insignificant”(候補: “insignificant”, “rounded”, “none”)
max_chars文字列を省略記号で切り詰める文字数の上限12L
max_rows中間を省略する行数の上限20L
max_cols中間を省略する列数の上限15L
show_all文字が小さくなっても全てのセルを描画するかの指定FALSE
fontsizeフォントサイズ(ポイント)、NULLはデバイスに合わせて自動調整NULL
familyフォントファミリー“mono”
palette配色、”mint”、”slate”、”warm”、”classic”または色の名前付きリストを指定NULL
show_dimnames描画するdimnames()の軸、”none”、”row”、”column”、”all”から複数指定可“all”
max_name_chars列名を切り詰める文字数の上限、行名にはmax_charsが適用8L
highlight_rows塗り分ける行、highlight_areaの簡易指定NULL
highlight_columns塗り分ける列、highlight_areaの簡易指定NULL
highlight_locations塗り分けるセルの位置、highlight_areaの簡易指定NULL
# 週×測定項目の行列をそのまま描画
paint_matrix(sokutei)

# 行・列・セルの添字を全て描画
paint_matrix(sokutei, show_indices = "all")

# 行名と列名を隠し、セルの添字のみを描画
paint_matrix(sokutei, show_dimnames = "none", show_indices = "cell")

# 最終週の行と血圧の列のマスクを、論理和で1つに結合
mask <- highlight_rows(sokutei, rows = 4) | highlight_columns(sokutei, columns = "血圧")
# 結合したマスクを渡し、行と列を同時に塗り分け
paint_matrix(sokutei, highlight_area = mask)

# 有効数字を5桁に広げ、灰色による桁の区別を無効化
paint_matrix(sokutei, sigfig = 5, subtle_digits = "none")

# ggplot2で同じ図を描画
gpaint_matrix(sokutei, show_indices = "all")

・週×測定項目の行列をそのままプロット

・行・列・セルの添字を全てプロット

・結合したマスクを渡し、行と列を同時に塗り分けてプロット

その他、コマンドのプロットは省略。

データフレームの可視化:paint_data_frameコマンド

オプション意味初期値
datadata.frameクラスを持つオブジェクトなし
show_indices描画する添字の種類、”none”、”cell”、”row”、”column”、”all”から複数指定可“none”
highlight_area塗り分けるセルを示す、データと同じ形の論理行列NULL
highlight_colorセルの背景を塗る色“lemonchiffon”
graph_title図の左上に表示するタイトルpaste0(“Data Object: “, deparse(substitute(data)))
graph_subtitleタイトルの直下に表示する副題、NULLは次元とクラスを自動表示、NAまたは””は非表示NULL
sigfig黒色で描画する有効数字の桁数、1から15の範囲で指定3L
subtle_digits灰色で描画する桁の判定方法“insignificant”(候補: “insignificant”, “rounded”, “none”)
max_chars文字列を省略記号で切り詰める文字数の上限12L
max_rows中間を省略する行数の上限10L
max_cols中間を省略する列数の上限10L
show_all文字が小さくなっても全てのセルを描画するかの指定FALSE
fontsizeフォントサイズ(ポイント)、NULLはデバイスに合わせて自動調整NULL
familyフォントファミリー“mono”
palette配色、”mint”、”slate”、”warm”、”classic”または色の名前付きリストを指定NULL
show_types列名の下に型タグの行を描画するかの指定TRUE
show_names列名の行を描画するかの指定TRUE
show_rownames行名を左の余白に描画するかの指定、NULLは独自の行名を持つ場合のみ描画NULL
name_align列名の寄せ方“center”(候補: “center”, “left”, “right”)
type_align型タグの寄せ方、name_alignとは独立に指定“center”(候補: “center”, “left”, “right”)
highlight_rows塗り分ける行、highlight_areaの簡易指定NULL
highlight_columns塗り分ける列、highlight_areaの簡易指定NULL
highlight_locations塗り分けるセルの位置、highlight_areaの簡易指定NULL
# 列ごとの型タグつきでデータフレームを描画
paint_data_frame(sanka)

# 型タグの行を隠し、列名を左寄せで描画
paint_data_frame(sanka, show_types = FALSE, name_align = "left")

# 列名を指定して歩数の列を塗り分け(paint_dfは同じコマンドの別名)
paint_df(sanka, highlight_columns = "歩数")

# 会員番号を行名として設定
rownames(sanka) <- c("A-01", "A-02", "B-01", "B-02", "B-03")
# 行名が左の余白に描かれ、セル内には添字が描かれることを確認
paint_data_frame(sanka, show_indices = "cell")

# 行名を描画せず、代わりに行番号の添字を左の余白に描画
paint_data_frame(sanka, show_rownames = FALSE, show_indices = "row")

# ggplot2で同じ図を描画
gpaint_data_frame(sanka)

show_rownamesの初期値はNULLで、この場合はデータフレームが独自の行名を持つときだけ行名がプロットされます。行番号がそのまま行名になっているデータフレームでは何もプロットされません。行名は列ではないため、上記の例で行名に設定した会員番号をsanka$会員番号として参照するとNULLになります。

・列ごとの型タグつきでデータフレームをプロット

・行名をプロットせず、代わりに行番号の添字を左の余白にプロット

その他、コマンドのプロットは省略。

リスト構造の可視化:paint_listコマンド

リストを、要素ごとに1列を割り当てて描画します。要素の長さがそろっていなくてもプロット可能です。ggplot2でプロットする場合はgpaint_listコマンドを使用します。

オプション意味初期値
dataクラスを持たない素のリスト、クラス付きのリストは描画対象外なし
summarise各要素を型と長さを示す1つのセルに要約して描画するかの指定FALSE
show_indices値の下に[[j]][i]形式の添字を描画するかの指定、”none”、”cell”、”all”から選択“none”
highlight_area塗り分けるセルを示す、位置×要素の論理行列NULL
highlight_colorセルの背景を塗る色“lemonchiffon”
graph_title図の左上に表示するタイトルpaste0(“Data Object: “, deparse(substitute(data)))
graph_subtitleタイトルの直下に表示する副題、NULLは要素数と長さの範囲とクラスを自動表示NULL
sigfig黒色で描画する有効数字の桁数、1から15の範囲で指定3L
subtle_digits灰色で描画する桁の判定方法“insignificant”(候補: “insignificant”, “rounded”, “none”)
max_chars文字列を省略記号で切り詰める文字数の上限12L
max_rows中間を省略する要素の長さの上限、要素ごとに個別に判定10L
max_cols中間を省略する要素数の上限8L
show_all文字が小さくなっても全てのセルを描画するかの指定FALSE
fontsizeフォントサイズ(ポイント)、NULLはデバイスに合わせて自動調整NULL
familyフォントファミリー“mono”
palette配色、”mint”、”slate”、”warm”、”classic”または色の名前付きリストを指定NULL
show_types要素名の下に型タグの行を描画するかの指定TRUE
show_names要素名の行を描画するかの指定、名前のない要素は[[2]]の形式で表示TRUE
name_align要素名の寄せ方“center”(候補: “center”, “left”, “right”)
type_align型タグの寄せ方、name_alignとは独立に指定“center”(候補: “center”, “left”, “right”)
gap隣り合う要素の列の間に挿入する空白の幅、列1つ分を1として指定0
highlight_rows塗り分ける位置、highlight_areaの簡易指定NULL
highlight_columns塗り分ける要素、highlight_areaの簡易指定NULL
highlight_locations塗り分けるセルの位置、highlight_areaの簡易指定NULL
# 要素の長さが異なるリストをそのままプロット
paint_list(kaijo)

# 値の下に[[j]][i]形式の添字をプロット
paint_list(kaijo, show_indices = "cell")

# 要素の列の間に空白を入れ、独立したベクトルの集まりであることを表現
paint_list(kaijo, gap = 0.5)

# 各要素を1セルに要約し、構造だけをプロット
paint_list(kaijo, summarise = TRUE)

# 要素名を指定して西部の列を塗り分け
paint_list(kaijo, highlight_columns = "西部")

# 全会場の1人目のみを塗り分け
paint_list(kaijo, highlight_rows = 1)

# ggplot2で同じ図をプロット
gpaint_list(kaijo, show_indices = "cell")

・値の下に[[j]][i]形式の添字をプロット

その他、コマンドのプロットは省略。

配列データの可視化:paint_arrayコマンド

3次元以上の配列を、スライスごとのブロックに分けてプロットします。行列やテーブルも配列として扱われます。ggplot2でプロットする場合はgpaint_arrayコマンドを使用します。

オプション意味初期値
dataarray、matrixとtableも配列として描画、1次元は描画対象外なし
show_indices描画する添字の種類、”none”、”cell”、”row”、”column”、”all”から複数指定可“none”
highlight_area塗り分けるセルを示す、データと同じ形の論理配列NULL
highlight_colorセルの背景を塗る色“lemonchiffon”
graph_title図の左上に表示するタイトルpaste0(“Data Object: “, deparse(substitute(data)))
graph_subtitleタイトルの直下に表示する副題、NULLは全体の形とクラスを自動表示、NAまたは””は非表示NULL
sigfig黒色で描画する有効数字の桁数、1から15の範囲で指定3L
subtle_digits灰色で描画する桁の判定方法“insignificant”(候補: “insignificant”, “rounded”, “none”)
max_chars文字列を省略記号で切り詰める文字数の上限12L
max_rows各ブロックの中間を省略する行数の上限、NULLはランクに応じた既定値を使用NULL
max_cols各ブロックの中間を省略する列数の上限、NULLはランクに応じた既定値を使用NULL
max_slices中間を省略するスライス数の上限4L
slices_per_rowスライスのブロックを1行に並べる枚数、NULLは配列本来の配置NULL
show_all文字が小さくなっても全てのセルを描画するかの指定FALSE
fontsizeフォントサイズ(ポイント)、NULLはデバイスに合わせて自動調整NULL
familyフォントファミリー“mono”
palette配色、”mint”、”slate”、”warm”、”classic”または色の名前付きリストを指定NULL
show_dimnames描画するdimnames()の軸、”none”、”row”、”column”、”slice”、”all”から複数指定可“all”
max_name_chars列名を切り詰める文字数の上限、行名にはmax_charsが適用8L
highlight_rows塗り分ける行、全スライスの同じ行が対象NULL
highlight_columns塗り分ける列、全スライスの同じ列が対象NULL
highlight_locations塗り分けるセルの位置、次元数と同じ列数の座標を指定NULL
# 3次元配列をスライスごとのブロックとしてプロット
paint_array(hosuu)

# ブロックを1行に1枚ずつ並べ、全てのセルをプロット
paint_array(hosuu, slices_per_row = 1, show_all = TRUE)

# 添字を、配列の次元数に合わせた[i, j, k]形式でプロット
paint_array(hosuu, show_indices = "all")

# 最終週の行を、全てのスライスで塗り分け
paint_array(hosuu, highlight_rows = 4)

# 中央会場の列を、前年と本年の両方で塗り分け
paint_array(hosuu, highlight_columns = "中央")

# スライス名をプロットせず、行名と列名だけをプロット
paint_array(hosuu, show_dimnames = c("row", "column"))

# ggplot2で同じ図をプロット
gpaint_array(hosuu)

・中央会場の列を、前年と本年の両方で塗り分け

強調表示するセルの指定:highlight_dataコマンド

各描画コマンドのhighlight_areaに渡す強調表示する論理マスクを作成します。行だけを指定するhighlight_rowsコマンド、列だけを指定するhighlight_columnsコマンド、セルの位置を指定するhighlight_locationsコマンドが用意されています。

オプション意味初期値
xベクトル、因子、行列、データフレームなど、いずれかの描画コマンドが扱える構造なし
rows行の位置、整数の添字、行名、論理マスクのいずれかで指定NULL
columns列の位置、整数の添字、列名、論理マスクのいずれかで指定NULL
locations2次元は行と列の組を並べたm行2列の行列、1次元は整数の添字で指定NULL
使用しない追加の引数なし
# 血圧の列を指す論理マスクを作成
highlight_columns(sokutei, columns = "血圧")
   [,1]  [,2] [,3]
[1,] FALSE FALSE TRUE
[2,] FALSE FALSE TRUE
[3,] FALSE FALSE TRUE
[4,] FALSE FALSE TRUE

# 最終週の行を指す論理マスクを作成
highlight_rows(sokutei, rows = 4)
  [,1]  [,2]  [,3]
[1,] FALSE FALSE FALSE
[2,] FALSE FALSE FALSE
[3,] FALSE FALSE FALSE
[4,]  TRUE  TRUE  TRUE

# 行と列の組を並べ、個別のセルを指す論理マスクを作成
highlight_locations(sokutei, rbind(c(1, 1), c(4, 3)))
### 出力は省略

# ベクトルでは整数の位置で要素を指定
highlight_data(steps, locations = which(steps < 8000))
### 出力は省略

# データフレームでは列名による指定も可能
highlight_data(sanka, columns = "歩数")
### 出力は省略

# 行と列を同時に指定すると、両者の和集合が対象
highlight_data(sokutei, rows = 4, columns = "血圧")
### 出力は省略

返り値は元のデータと同じ形の論理オブジェクトです。1次元の構造には論理ベクトル、行列やデータフレームには論理行列、3次元以上の配列には同じ形の論理配列が返ります。返り値が論理型であるため、論理演算子で複数のマスクを組み合わせることが可能です。

必要なデバイスサイズの算出:paint_sizeコマンド

オプション意味初期値
dataベクトル、行列、データフレームなど、いずれかの描画コマンドが扱える構造なし
show_all、show_indices、layout、max_rowsなど、図の形に影響する描画コマンドの引数なし
min_pt可読性の下限とするフォントサイズ(ポイント)5
familyフォントファミリー、現在は算出結果に影響しない“mono”
units返り値の単位“in”(候補: “in”, “cm”, “px”)
dpiunits = “px”のときに使用する1インチあたりのピクセル数96
# データフレームのプロットに必要なサイズをインチ単位で算出
paint_size(sanka)
 width height 
   4.3    1.4 

# 省略せずに全体をプロットする場合のサイズを、96 dpiのピクセル単位で算出
paint_size(sanka, show_all = TRUE, units = "px")
 width height 
   408    134 

# 添字をプロットする分だけ広がるサイズを算出
paint_size(hosuu, show_indices = "all")
 width height 
   7.9    1.9 

# 横並びのベクトルに必要なサイズをセンチメートル単位で算出
paint_size(steps, layout = "horizontal", units = "cm")
 width height 
     8      2 

# 可読性の下限を8ポイントに引き上げて算出
paint_size(kaijo, summarise = TRUE, min_pt = 8)
 width height 
   4.2    1.2 

返り値はwidthとheightを持つ名前付き数値ベクトルです。単位がインチのままであれば、png()やknitrのチャンクヘッダにそのまま使用できます。

# 添字つきで配列をプロットする場合に必要なサイズを算出
dev_size <- paint_size(hosuu, show_indices = "all")

# 算出したサイズをそのままpng()に渡してファイルへ保存
png("hosuu.png", width = dev_size[["width"]], height = dev_size[["height"]],
    units = "in", res = 96)

# 開いたデバイスに配列の図をプロット
paint_array(hosuu, show_indices = "all")

# デバイスを閉じてファイルを確定
dev.off()

日本語データを扱う際の注意点

本パッケージは、セルの幅を「文字数×0.6em」という半角文字を基準にした計算で見積もっています。そのため、全角文字を含むデータでは、paint_sizeコマンドが返すサイズがやや小さめに算出されます。算出値をそのままpng()に渡すと、可読性の下限を下回った旨の警告が表示される場合があります。

警告文には拡大後の推奨サイズが具体的に示されるため、その値を使ってデバイスを開き直せば解決します。あらかじめ余裕を持たせる場合は、paint_sizeコマンドが返す幅を1.5倍から1.7倍程度に広げておくと安定です。また、ラベル内容を短くする、fontsizeを指定するなども有効だと考えます。

# 会場名に全角文字を含むデータフレームを作成
kaijo_df <- data.frame(
  会場名 = c("中央公民館", "東部保健センター", "西部体育館"),
  参加者数 = c(12L, 8L, 15L))

# 必要なサイズを算出
dev_size <- paint_size(kaijo_df)

# 算出値をそのまま使うと、可読性の下限を下回る警告が表示される
png("kaijo1.png", width = dev_size[["width"]], height = dev_size[["height"]],
    units = "in", res = 96)

# データフレームの図をプロット
paint_data_frame(kaijo_df)

# デバイスを閉じてファイルを確定
dev.off()

# 警告文が提示するサイズに広げて保存し直す
png("kaijo2.png", width = 6.6, height = 1.9, units = "in", res = 96)

# 同じ図を、余裕のあるサイズでプロット
paint_data_frame(kaijo_df)

# デバイスを閉じてファイルを確定
dev.off()


この記事が誰かの役に立ちますように。

スポンサーリンク
価格および配送状況は変更される場合があります。購入時は商品ページをご確認ください。
当サイトに表示されている商品情報はAmazonから提供されたものであり、更新または削除される場合があります。
karada-goodはAmazonアソシエイトとして、適格販売により収入を得ています。