2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【R】 dplyr::group_nestを使って集計する

Last updated at Posted at 2020-11-07

はじめに

これまでRはちょっと難しそうだなと感じがしていて、複雑な統計計算以外には使っていなかったのですが、tidyverseが意外と簡単そうな気がしましたので、最近また使い始めました。なかでも、tidyverseのdplyrパッケージにあるgroup_nestが便利そうなのですが、使い方がよくわかりませんでした。

データとして、国土交通省が公開している
これまでに公表した面積調(昭和63年以降)にある「令和元年7月以降(令和2年7月まで)[CSV:154KB]」を読み込んで集計してみました。

library(tidyverse)
library(magrittr)

area_data <- read_csv("R1_R2_all_mencho.csv", skip=4, locale=locale(encoding="CP932"))

このファイルのエンコードはCP932になっており、ヘッダの文字に㎡が使われています。
はじめにread.csv("R1_R2_all_mencho.csv", skip=4, fileEncoding="CP932")で読み込んでみたのですが、㎡がうまく扱えませんでした。

市区町村以外のデータも含まれていましたので、市区町村だけのデータにします。

area_data %<>% select(1,2,4,5) %>% rename(`面積`=starts_with("令和"))
area_data %<>% filter(!is.na(`市区町村`) & !str_detect(`市区町村`, "\\(") & !is.na(`標準地域コード`))
area_data %<>% select(-`標準地域コード`)

area_dataにはこのようなデータが入っています。
image.png

都道府県別に集計する

g1 <- area_data %>% group_nest(`都道府県`)

都道府県別にグループ化しています。説明があとになってしまいましたが、ここではRStudioを使っています。g1の表示です。各都道府県が1行になっています。
image.png
data列の表アイコンをクリックすると、その都道府県のデータが表示されます。
image.png

data列のデータ全体はg1$dataで表示されます。都道府県別に分割されたtibbleのリストです。group_splitと似た形式になっていますが、group_nestでは都道府県が抜けています。

今回は、市町村合併で減少しましたが「村」について集計して見ます。
まず、tibble(またはdata.frame)データから、村だけを取り出す関数を作ってみます。

mura <- function(x){filter(x, str_ends(`市区町村`, "村"))}

「市区町村」で村で終わるものだけを取り出します。グループ化前のarea_dataデータを使って試してみます。
mura(area_data)
村だけが抽出されてることがわかります。
次にgroup_nestされたデータに適用してみます。上に示したg1$data出力を処理できるようにすると良いのですが、..
purrrにあるmapを使います。map(g1$data, ~mura(.))とすると村だけに絞り込まれたリストが返されます。

g1 %<>% mutate(`村`=map(data, ~mura(.x)))
g11 <- g1 %>% unnest(`村`) # おまけ

これで「村」列に村だけに絞り込まれたデータが追加され、g11には展開されたデータが入ります。わざわざ関数を作らなくても、無名関数で

g1 %<>% mutate(`村`=map(data, function(x){filter(x, str_ends(`市区町村`, "村"))}))
g1 %<>% mutate(`村`=map(data, ~filter(.x, str_ends(`市区町村`, "村"))))

のように書くこともできます。
次に、村の数と面積合計を集計してみます。

g1 %<>% mutate(`村数`=map_int(`村`, nrow))
g1 %<>% mutate(`村面積合計`=map_dbl(`村`, ~sum(.x$`面積`)))

mapの中の関数をどう書いていいのかよく分からなくなってしまいます。その時は上に書いたように別に関数を作って確認しています。
ここではmapではなくmap_intやmap_dblとしています。mapだとリストを返し、そのままでは数値としての処理ができなくなってしまいます。(unnestを使えばできますが)数値ベクトルにしておく必要があります。

goup_nestだと表の中に全データが残っていますし、RStudioを使うとデータ構造がわかりやすく表示できますので便利です。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?