投稿

Pythonで、e-Statの市区町村別の人口、面積、年齢データをCSVに変換する

本日はちょっとPython篇。なぜっていうと、Pythonしか使えないよーって人がいるから。こういうテーブルを加工する系はR(というかdplyr)のほうが断然使いやすいとは思いますが、まあバイリンガルになるのも良いでしょう。 例えば、欲しいのは市区町村別の人口や面積や平均年齢のデータ。で、e-Statに置いてあるのを発見するも( 国勢調査 都道府県・市区町村別の主な結果 都道府県・市区町村別の主な結果 | ファイル | 統計データを探す | 政府統計の総合窓口 )、ファイルがエクセルだわ、列名が自治体コードと都道府県名を連結した文字列だわで、なんとも使いづらい。ちゃちゃっと加工しちゃえばいいんでしょうが、全国のいろんなところで、いろんな人が同じような作業をするのが無駄なので、サンプルコードとそれで出力されたCSVファイルを置いておきます。 やっているのは、 "openpyxl"でエクセルファイルを読み込みデータフレームに変換 必要な行や列を取り出す 正規表現で列名を加工 CSVファイルに書き出し あたりです。 import os import openpyxl import pandas as pd os.chdir(r'(エクセルファイルを置いたパス)') # ワークブックを開いた後、ワークシートを指定する # 読み込んでいるのは、e-Statの国勢調査データ wb = openpyxl.load_workbook('major_results_2020.xlsx') ws = wb['第1面事項_2020年'] df = pd.DataFrame(ws.values) # データが入っているのは9行目以降 # 0, 1, 4, 10, 11, 12列にはそれぞれ # 都道府県、市区町村、人口、面積、平均年齢が入っている df = df.loc[9:, [0, 1, 4, 10, 12]] dic = {0:'都道府県', 1:'市区町村', 4:'人口', 10:'面積', 12:'平均年齢'} df = df.rename(columns=dic) # 列名をつける # アンダースコアの前の部分が、

Rのデータフレームで、列名指定で列名の一部を変更する方法

まずは、動作確認用のサンプルコードです。 # サンプルコードのデータフレーム age    <- c( 20,  30,  40) height <- c(170, 168, 175) wait   <- c( 67,  64,  70) df <- data.frame(age, height, wait) df   age height wait 1  20    170   67 2  30    168   64 3  40    175   70 ちょ、待てよ。体重のweightがwaitになってんじゃん。 ってことで、この列名だけ変更したいと。 列名全体のベクトルをまとめて指定して変更する方法↓ names(df) <- c("age", "height", "weight") とか、 インデックス番号を使って、一部を変更する方法↓ names(df)[3] <- "weight" とかがあるんですが、列数がめちゃめちゃ多いデータだと数えるのが大変だし、列の削除や挿入に対してロバストでないし。できれば、列名の指定で変更を行いたい。 ちょっとコードがごちゃごちゃしますが、↓こんな感じでできます。 names(df)[ which( names(df)=="wait" ) ] <- "weight" 内側から順に見ていくと・・・ names(df)=="wait" で、列名が "wait" になっている位置が FALSE FALSE TRUE というベクトルで返ってきます。 それを which() に渡すと、「3」というインデックス番号が返ってきます。 なのでこの「3」を names(df)[] に対するインデックスの指定に使えばOKというわけです。

reorderを使ってggplotの棒グラフの並び順を降順にする方法

イメージ
# サンプルデータの作成 fruits <- c("apple","durian","orange") count  <- c(2, 1, 3) df <- data.frame(fruits, count) df # 中身の確認   fruits count 1  apple     2 2 durian     1 3 orange     3 このデータを使って、ggplotで棒グラフを描いてみると、 library(ggplot2) ggplot(df, aes(x=fruits, y=count))   + geom_bar(stat="identity") 並び順はデータのまま 当然ながら、棒の順番はデータ通りに、2、1、3と並びますね。 これをソートしたい場合は、reorderを使います↓ ggplot(df, aes( x=reorder(fruits, count) , y=count)) +   geom_bar(stat="identity") reorderすると昇順に並ぶ x軸はfruitsなんだけど、reorder関数の第二引数であるcountの値で並べ替えてから使ってね、という指定です。 で、次の課題です。 reorderを使うと、昇順で1、2、3という並びになりましたが、これを降順の3、2,1という並びにしたいときは、どうやればいいか。 データフレームをソートするときなんかに使うorder関数でいうところの「decreasing=TRUE」みたいな指定があればいいのですが、reorder関数にはそのようなオプションはなさそうです。 で、実はごく簡単で、reorderの第二引数(count)の値の正負が逆になれば、順番も逆になるじゃんという理屈です。 ggplot(df, aes(x=reorder(fruits, -count ), y=count)) +   geom_bar(stat="identity") reorder関数の第二引数にマイナスをつければ降順にできる 無事、降順に並んでくれました。

Rのデータフレームから少数の行を削除する

例えば、↓こんなデータがあったとして、 # サンプルデータの作成 name  <- c("Anne", "Bob", "Carl", "Dann", "Eric", "Fred") fruits <- c("orange", "apple", "orange", "durian", "orange", "apple") df <- data.frame(name, fruits) df # 中身を見てみる   name fruits 1 Anne orange 2  Bob  apple 3 Carl orange 4 Dann durian 5 Eric orange 6 Fred  apple みんなの好きな果物のデータだとして、1人しかいないような少数派の行は除去したいと。この例だと、ダンのドリアンを取り除きたいと。 ddplyを使って度数をカウントし、新たに度数(count)の列として追加(transform)。 library(plyr) ddply(df, "fruits", transform, count=length(fruits))   name fruits count 1  Bob  apple     2 2 Fred  apple     2 3 Dann durian     1 4 Anne orange     3 5 Carl orange     3 6 Eric orange     3 で、このcount列を条件として、データフレームをフィルタすればいいかなと。 dd <- ddply(df, "fruits", transform, count=length(fruits)) dd[ dd$count > 1, ] # 少数派の行を削除   name fruits count 1  Bob  apple     2 2 Fred  apple     2 4 Anne orange    

table関数の出力結果をmatrixに変換して、corresp関数で対応分析を行う(R言語)

イメージ
 ↓この本に載っていた例で、 Rによるデータサイエンス データ解析の基礎から最新手法まで library(MASS) caith        fair red medium dark black blue    326  38    241  110     3 light   688 116    584  188     4 medium  343  84    909  412    26 dark     98  48    403  681    85 ↑このようなデータ(縦に並んでいるのが目の色、横に並んでいるのが髪の色)に対して、↓こんな感じで対応分析を行う、という例が載っていました。 caith.ca <- corresp(caith, nf=4) biplot(caith.ca) Rでのcaithデータの対応分析結果 と、ここまでが前置き。 今、手元にあるのが↓こんなデータだった、としましょう。 gender <- c("M","M","M","M","F","F","F","F","F","F") blood  <- c("A","B","B","O","A","B","A","O","A","AB") gender.blood <- data.frame(gender, blood) gender.blood    gender blood 1       M     A 2       M     B 3       M     B 4       M     O 5       F     A 6       F     B 7       F     A 8       F     O 9       F     A 10    

Rで、データフレームの中身を一括で因子型に変換する方法

例えば、Rで↓こんなデータを扱っているとします。 # サンプルデータを作る Q1 <- c(1, 1, 2, 2) Q2 <- c(1, 2, 1, 2) Q3 <- c(1, 2, 3, 1) df <- data.frame(Q1, Q2 ,Q3) # 中身の確認 df   Q1 Q2 Q3 1  1  1  1 2  1  2  2 3  2  1  3 4  2  2  1 読み込んだときの都合か何かで、データはinteger型とかnumeric型になっていると。 でも、実は質問 Q1、Q2、Q3に、1:はい、2:いいえ、3:どちらともいえない、とかで答えたもので、因子型として扱いたい。 多重対応分析のmcaとかを使おうとすると、 mca(df = df) でエラー: all variables must be factors が出ちゃうとか、そんなシチュエーション。 因子型に変換したいときには、as.factor関数ですが、これはデータフレームに対しては使えない。 こんな時は、あの一家。そう、applyファミリーの登場です。 lapplyを使って、1列ごとにas.factor関数を適用、リストとして返ってきたものを、またデータフレームに戻してやるという流れです。 df.fctr <- data.frame( lapply(df, as.factor) ) # 型の確認 df.fctr$Q1  [1] 1 1 2 2 Levels: 1 2 無事、因子型になりました。

Rでヒストグラムの一部に色をつける(colオプション指定で可)

イメージ
「R ヒストグラム 一部 色をつける」で検索してみると、hist関数でヒストグラムを描いた後に、polygon関数で色をつける、なんて方法がヒットしました。 polygon使えばなんでもできそうだけど、なんか、ちょっと違うよなあ、とか思ってしまいまして。 で、実はhist関数のcolオプションでも、できるんですよね。 colオプションに1つの値(スカラー)を指定すると、全体が一色で塗りつぶされてしまいますが、ここにベクトルを指定すると、それぞれの棒の色を指定することができます。 例えば、ヒストグラムに10個のビンがあって、それぞれを任意の色で塗りたい場合は、10個の要素を持つベクトルをcolオプションに指定すればOKです。 set.seed(0)       # 再現性のために rd <- rnorm(100) # 100個の乱数 cols <- c("white", "white", "red"  , "white", "white",           "blue" , "white", "white", "white", "white") hist(rd, col=cols) ヒストグラムの一部に色をつける 色を塗りたくない場合は(パワポなどの「塗りつぶしなし」みたいな感じ)、色名の代わりにNAを指定すればいいです。 cols <- c(NA    , NA, "red", NA, NA,           "blue", NA, NA   , NA, NA) hist(rd, col=cols) 最初の例と全く同じ見た目になると思いますが、add=T指定で重ねたときなんかに差がでますね。 階級がいっぱいあって、いちいち全部書き出すのが面倒なときは、下記のような感じで、塗りたいところだけを指定すればいいですね。 cols <- rep("white", 100) # ”white”を詰めた、長めのベクトルを作って