Rでデータフレームを部分抽出後、ベクトルや行列に変換する
例えば↓こんな感じで、各市町村の人口データがあったとします。
で、人口や男女比を比較するために、それぞれの市町村に対してグラフを描いてみようとしたとします。
じゃあ、1行ごとにループで回しながら、barplotあたりを使って、グラフを描いてみようとしまして、↓こんな風にスクリプトを書くと(iがループのカウンタだと思ってね)、
なんでだ?と思って、切り出される部分をチェックしてみると、
じゃあ、ベクトルに変換してあげよう。
ラベル(maleとかfemale)の情報は消えちゃったけど、まあなんとかなったと。
エラーメッセージには「ベクトルか行列でなければなりません」とあったから、今度は行列にしてみよう↓
列名が残っているおかげで、軸ラベルがそのまま出てくれるので、こっちの方がいいですね。
ちなみに↓こんな風に書いても、同じ動きになります。
転置したときに行列に変換されるからですね。文字数的には少なく済みますが、あとで見たときや、他の人が見たときに混乱するかもしれないので、こういう書き方はやめた方がよさそうです。
で、ここからは補足になるんですが、もともとデータフレームを入力とするggplotを使ってみたらどうだろうかと。
前述のデータフレームはwideフォーマットなので、いったんlongフォーマットに変換します。
「dl_l」という名前のロングフォーマットのデータフレームに変換できたので、これをggplotに渡します。

各市町村の男女人口や比率を比較したいなら、この可視化がよさげですね。
でも、このデフォルトのmaleとfemaleの色の割り当ては、無用な勘違いを生んでしまいそうです。
ggplotで、塗りつぶし(fill)の色を変更する方法については、
Rグラフィックスクックブック ―ggplot2によるグラフ作成のレシピ集

↑この書籍の「レシピ3.2 棒をグループ化する」のところなんかに、カラーパレットとしてbrewerパレットを使うレシピが載っていたりします。
その方法を使ってみると↓

はい、それっぽい色になりました。
やり方については、上記の書籍を買って読んでみてください。(最後はアフィリエイトかよ!)
city <- c("A市", "B町", "C村", "D市") male <- c(95, 49, 26, 45) female <- c(99, 51, 24, 55) df <- data.frame(city, male, female) df city male female 1 A市 95 99 2 B町 49 51 3 C村 26 24 4 D市 45 55
で、人口や男女比を比較するために、それぞれの市町村に対してグラフを描いてみようとしたとします。
じゃあ、1行ごとにループで回しながら、barplotあたりを使って、グラフを描いてみようとしまして、↓こんな風にスクリプトを書くと(iがループのカウンタだと思ってね)、
# i行目の男女人口を棒グラフにしたい・・・ barplot(df[i, c("male", "female")]) barplot.default(df[i, c("male", "female")]) でエラー: 'height' はベクトルか行列でなければなりません
なんでだ?と思って、切り出される部分をチェックしてみると、
df[i, c("male", "female")] male female 1 95 99 class(df[i, c("male", "female")]) [1] "data.frame"構成要素としては、2つの数値の並びになっているもの、型がデータフレームなもんだから、barplotにそのまま渡すとエラーになってしまうのね。ちなみに、円グラフのpie関数なんかでも同じで、データフレームのままでは受け取ってくれない。
じゃあ、ベクトルに変換してあげよう。
barplot(as.vector(df[i, c("male", "female")], mode="numeric"))
![]() |
as.vector後にbarplotに渡したもの |
ラベル(maleとかfemale)の情報は消えちゃったけど、まあなんとかなったと。
エラーメッセージには「ベクトルか行列でなければなりません」とあったから、今度は行列にしてみよう↓
barplot( as.matrix(df[i, c("male", "female")]) )
![]() |
as.matrix後にbarplotに渡したもの |
列名が残っているおかげで、軸ラベルがそのまま出てくれるので、こっちの方がいいですね。
ちなみに↓こんな風に書いても、同じ動きになります。
barplot( t(t(df[1, c("male", "female")])) )
転置したときに行列に変換されるからですね。文字数的には少なく済みますが、あとで見たときや、他の人が見たときに混乱するかもしれないので、こういう書き方はやめた方がよさそうです。
で、ここからは補足になるんですが、もともとデータフレームを入力とするggplotを使ってみたらどうだろうかと。
前述のデータフレームはwideフォーマットなので、いったんlongフォーマットに変換します。
library(reshape2) # longフォーマットに変換 df_l <- melt( df, id.vars="city", variable.name="gender", value.name="population" ) df_l city gender population 1 A市 male 95 2 B町 male 49 3 C村 male 26 4 D市 male 45 5 A市 female 99 6 B町 female 51 7 C村 female 24 8 D市 female 55
「dl_l」という名前のロングフォーマットのデータフレームに変換できたので、これをggplotに渡します。
library(ggplot2) # A市の行だけ取り出してプロット ggplot( df_l[city=="A市", ], aes(x=gender, y=population)) + geom_bar(stat="identity")
![]() |
1行だけ取り出してggplot |
うん、想定通りに表示できました。
じゃあ、これをループで回す? いやいや、ggplotなら、いっぺんにプロットできますよね。
ggplot( df_l, aes(x=city, y=population, fill=gender)) +
geom_bar(stat="identity", position="dodge")

各市町村の男女人口や比率を比較したいなら、この可視化がよさげですね。
でも、このデフォルトのmaleとfemaleの色の割り当ては、無用な勘違いを生んでしまいそうです。
ggplotで、塗りつぶし(fill)の色を変更する方法については、
Rグラフィックスクックブック ―ggplot2によるグラフ作成のレシピ集

↑この書籍の「レシピ3.2 棒をグループ化する」のところなんかに、カラーパレットとしてbrewerパレットを使うレシピが載っていたりします。
その方法を使ってみると↓

はい、それっぽい色になりました。
やり方については、上記の書籍を買って読んでみてください。(最後はアフィリエイトかよ!)
コメント
コメントを投稿