2016年の参議院選挙比例区の実際の投票数を用いてドント方式の計算方法を確認する. 講義では簡単な数値例で説明したが, 規模が大きくなっても同じように計算できる.
必要なパッケージを読み込む.
library(dplyr)
投票数をデータフレームに投入. データは例えば, http://www.asahi.com/senkyo/senkyo2016/kaihyo/C01.html から取得できる.
party = c("自民", "民進", "公明", "共産", "お維新", "社民", "生活",
"こころ", "改革", "幸福")
nvote = c(20114788, 11750965, 7572960, 6016195, 5153584, 1536238, 1067300,
734024, 580653, 366815)
votes = data.frame(party, nvote)
votes
## party nvote
## 1 自民 20114788
## 2 民進 11750965
## 3 公明 7572960
## 4 共産 6016195
## 5 お維新 5153584
## 6 社民 1536238
## 7 生活 1067300
## 8 こころ 734024
## 9 改革 580653
## 10 幸福 366815
改選議席数は 48 である.
nseat = 48
R では割り算の商は %/%
を使う. 議席数を2で割った商を追加したテーブルを作成してみよう.
votes %>%
mutate(divide_by_2 = nvote %/% 2)
## party nvote divide_by_2
## 1 自民 20114788 10057394
## 2 民進 11750965 5875482
## 3 公明 7572960 3786480
## 4 共産 6016195 3008097
## 5 お維新 5153584 2576792
## 6 社民 1536238 768119
## 7 生活 1067300 533650
## 8 こころ 734024 367012
## 9 改革 580653 290326
## 10 幸福 366815 183407
nvote
と書かれた列 (得票数を表す) の中に, nvote2
の最大数より大きい数字があれば, 政党は1議席確保できる. nvote2
の最大は 10057394
なので, 自民と民進が1議席を確保できる.
votes %>%
mutate(divide_by_2 = nvote %/% 2) %>%
mutate(step1 = nvote > max(divide_by_2)) %>%
select(party, step1)
## party step1
## 1 自民 TRUE
## 2 民進 TRUE
## 3 公明 FALSE
## 4 共産 FALSE
## 5 お維新 FALSE
## 6 社民 FALSE
## 7 生活 FALSE
## 8 こころ FALSE
## 9 改革 FALSE
## 10 幸福 FALSE
step2 では, 3
で割った商を計算し, その最大よりも大きい数字が 1
で割った商と 2
で割った商の中にあればその政党が議席を獲得する.
これを順番に実行していけばいいのだが, 議席数が大きくなると大変なので自動化しよう.
自然数で割って, その商を記録していくというのが基本的な考え方である.
dhondt0 = votes %>%
mutate(divide_by = 1, value = nvote %/% 1) %>%
select(party, divide_by, value)
dhondt0
## party divide_by value
## 1 自民 1 20114788
## 2 民進 1 11750965
## 3 公明 1 7572960
## 4 共産 1 6016195
## 5 お維新 1 5153584
## 6 社民 1 1536238
## 7 生活 1 1067300
## 8 こころ 1 734024
## 9 改革 1 580653
## 10 幸福 1 366815
2 ステップ目は次の様に計算できる.
temp = votes %>%
mutate(divide_by = 2, value = nvote %/% 2) %>%
select(party, divide_by, value)
dhondt0 %>%
rbind(mutate(temp))
## party divide_by value
## 1 自民 1 20114788
## 2 民進 1 11750965
## 3 公明 1 7572960
## 4 共産 1 6016195
## 5 お維新 1 5153584
## 6 社民 1 1536238
## 7 生活 1 1067300
## 8 こころ 1 734024
## 9 改革 1 580653
## 10 幸福 1 366815
## 11 自民 2 10057394
## 12 民進 2 5875482
## 13 公明 2 3786480
## 14 共産 2 3008097
## 15 お維新 2 2576792
## 16 社民 2 768119
## 17 生活 2 533650
## 18 こころ 2 367012
## 19 改革 2 290326
## 20 幸福 2 183407
ステップ数が一番大きくなるのは, 1つの政党がすべての議席を確保するケースであり, この場合は議席数と同じだけステップが必要である. もっと計算量を節約することもできる だろうけど, この程度の無駄は許してしまおう.
同じような計算を繰り返し実行するときには for
を使う.
dhondt = data.frame()
for (i in 1:nseat){
temp = votes %>%
mutate(divide_by = i, value = nvote %/% i) %>%
select(party, divide_by, value)
dhondt =
dhondt %>% rbind(temp)
}
最初の20行は次のようになる.
head(dhondt, 20)
## party divide_by value
## 1 自民 1 20114788
## 2 民進 1 11750965
## 3 公明 1 7572960
## 4 共産 1 6016195
## 5 お維新 1 5153584
## 6 社民 1 1536238
## 7 生活 1 1067300
## 8 こころ 1 734024
## 9 改革 1 580653
## 10 幸福 1 366815
## 11 自民 2 10057394
## 12 民進 2 5875482
## 13 公明 2 3786480
## 14 共産 2 3008097
## 15 お維新 2 2576792
## 16 社民 2 768119
## 17 生活 2 533650
## 18 こころ 2 367012
## 19 改革 2 290326
## 20 幸福 2 183407
最後の20行は次のようになっている.
tail(dhondt, 20)
## party divide_by value
## 461 自民 47 427974
## 462 民進 47 250020
## 463 公明 47 161126
## 464 共産 47 128004
## 465 お維新 47 109650
## 466 社民 47 32685
## 467 生活 47 22708
## 468 こころ 47 15617
## 469 改革 47 12354
## 470 幸福 47 7804
## 471 自民 48 419058
## 472 民進 48 244811
## 473 公明 48 157770
## 474 共産 48 125337
## 475 お維新 48 107366
## 476 社民 48 32004
## 477 生活 48 22235
## 478 こころ 48 15292
## 479 改革 48 12096
## 480 幸福 48 7641
この大きなデータフレームを value
列に関して大きい順に並べ替えて, 上位48を取り出せばよい.
dhondt %>%
mutate(rank = rank(-value)) %>%
filter(rank <= nseat)
## party divide_by value rank
## 1 自民 1 20114788 1
## 2 民進 1 11750965 2
## 3 公明 1 7572960 4
## 4 共産 1 6016195 6
## 5 お維新 1 5153584 8
## 6 社民 1 1536238 31
## 7 生活 1 1067300 47
## 8 自民 2 10057394 3
## 9 民進 2 5875482 7
## 10 公明 2 3786480 12
## 11 共産 2 3008097 14
## 12 お維新 2 2576792 17
## 13 自民 3 6704929 5
## 14 民進 3 3916988 11
## 15 公明 3 2524320 18
## 16 共産 3 2005398 23
## 17 お維新 3 1717861 27
## 18 自民 4 5028697 9
## 19 民進 4 2937741 15
## 20 公明 4 1893240 25
## 21 共産 4 1504048 33
## 22 お維新 4 1288396 38
## 23 自民 5 4022957 10
## 24 民進 5 2350193 20
## 25 公明 5 1514592 32
## 26 共産 5 1203239 41
## 27 自民 6 3352464 13
## 28 民進 6 1958494 24
## 29 公明 6 1262160 39
## 30 自民 7 2873541 16
## 31 民進 7 1678709 28
## 32 公明 7 1081851 45
## 33 自民 8 2514348 19
## 34 民進 8 1468870 34
## 35 自民 9 2234976 21
## 36 民進 9 1305662 37
## 37 自民 10 2011478 22
## 38 民進 10 1175096 43
## 39 自民 11 1828617 26
## 40 民進 11 1068269 46
## 41 自民 12 1676232 29
## 42 自民 13 1547291 30
## 43 自民 14 1436770 35
## 44 自民 15 1340985 36
## 45 自民 16 1257174 40
## 46 自民 17 1183222 42
## 47 自民 18 1117488 44
## 48 自民 19 1058673 48
獲得議席数をカウントするには次のようにすればよい.
dhondt %>%
mutate(rank = rank(-value)) %>%
filter(rank <= nseat) %>%
group_by(party) %>%
summarize(seats = n()) %>%
arrange(desc(seats)) %>%
as.data.frame()
## party seats
## 1 自民 19
## 2 民進 11
## 3 公明 7
## 4 共産 5
## 5 お維新 4
## 6 生活 1
## 7 社民 1