この質問文を橋本氏は自己責任論を支持するかどうかを問うものの一つとして説明している(263ー264ページ)。しかし、「貧困になったのは努力しなかったからだ」という考えとは方向性が異なるように思う。
「努力しさえすれば、誰でも豊かになることができる」という言葉は、本来は「階級や出自による固定化を拒否する、開かれた流動性への希望」を語るものであり、それに対し、自己責任論は「現存する格差や困窮の苦痛から、社会や他者が免責されるための理論武装」なのではないだろうか。
橋本氏の著書の図表8・2「格差についての認識と支持政党」の「d.『努力しさえすれば、誰でも豊かになることができる』と支持政党」に注目してみた。なお、「とてもそう思う」から「まったくそう思わない」までを、順に「選択肢1」から「選択肢4」に割り当てている。
橋本氏のグラフのデータをもとにして、パーセント計算の方向を変えてみると、「努力しさえすれば、誰でも豊かになることができる」かどうかという質問に対する回答は、野党と「支持なし」の分布が類似している——両方のグループで「努力しさえすれば」という考えは相対的にあまり受け入れられていない。また、その逆の意味で、自民と維新の分布が類似している。
回答の類似性から浮かび上がる2グループの基本的な相違、また、同じグループに入るが一方は野党支持で、他方は——実はこれが最も人数が多い——支持する政党なしとなる要因に注目すべきなのであろう。
これらのことの意味をきちんと理解することは政治的に重要なことだと推測する。
【参考】R 実行プログラム(クリックで展開)
## 1
```{r,out.width="100%"}
library(ggplot2)
library(dplyr)
library(tidyr)
# 1. データの定義(ワイドフォーマット)
raw_data <- data.frame(
party = c("自民", "公明", "維新", "野党", "支持なし"),
Choice1 = c(28.6, 2.4, 13.8, 8.3, 47.0),
Choice2 = c(25.0,2.7,11.8,7.2,53.2),
Choice3 = c(16.6,2.4,9.2,8.7,63.0),
Choice4 = c(14.0,2.0,9.5,12.5,62.0)
)
knitr::kable(raw_data)
# ロングフォーマットに変換し、因子(Factor)の順序を設定
df_total <- raw_data %>%
pivot_longer(cols = starts_with("Choice"), names_to = "choice", values_to = "percentage") %>%
mutate(
choice = case_when(
choice == "Choice1" ~ "選択肢1 (5.1%)",
choice == "Choice2" ~ "選択肢2 (28.6%)",
choice == "Choice3" ~ "選択肢3 (49.3%)",
choice == "Choice4" ~ "選択肢4 (17.0%)"
),
choice = factor(choice, levels = c("選択肢1 (5.1%)", "選択肢2 (28.6%)", "選択肢3 (49.3%)", "選択肢4 (17.0%)")),
party = factor(party, levels = c("支持なし", "野党", "維新", "公明", "自民")) # 下から積み上げる順序
)
# 2. ANFフォーマット用の定数定義
AONF_CAPTION <- "Archives from 2026 Onward and Notes for the Future\n2026年以降の記録 | https://ab.cocolog-nifty.com/note/"
# 3. 積み上げ棒グラフの描画
ggplot(df_total, aes(x = choice, y = percentage, fill = party)) +
geom_bar(stat = "identity", width = 0.5, position = "stack") +
# 5%以上の領域にパーセンテージの数値を表示
geom_text(aes(label = if_else(percentage >= 5.0, paste0(percentage, "%"), "")),
position = position_stack(vjust = 0.5), size = 3, color = "black") +
scale_fill_brewer(palette = "Pastel1", direction = -1) +
labs(
title = "選択肢別 支持政党の内訳比較",
x = "選択肢(全体における割合)",
y = "選択肢内での割合 (%)",
fill = "支持政党",
caption = AONF_CAPTION
) +
theme_minimal(base_family = "HiraKakuProN-W3") +
theme(
legend.position = "bottom",
plot.caption = element_text(size = 8, hjust = 1, color = "gray30"),
plot.title = element_text(face = "bold", hjust = 0.5),
axis.text.x = element_text(size = 10)
)
```
## 2
```{r,out.width="100%"}
library(ggplot2)
library(dplyr)
library(tidyr)
# 1. 元データの定義(各選択肢内の政党構成比 %)
df_raw <- data.frame(
party = c("自民", "公明", "維新", "野党", "支持なし"),
p_choice1 = c(28.6, 2.4, 13.8, 8.3, 47.0),
p_choice2 = c(25.0,2.7,11.8,7.2,53.2),
p_choice3 = c(16.6,2.4,9.2,8.7,63.0),
p_choice4 = c(14.0,2.0,9.5,12.5,62.0)
)
# 各選択肢の全体人数(総計 43,820人)
n_total <- 43820
n_choice1 <- n_total * 0.051
n_choice2 <- n_total * 0.286
n_choice3 <- n_total * 0.493
n_choice4 <- n_total * 0.170
# 2. 人数(度数)への変換と、政党ベースでの再集計
df_party_distribution <- df_raw %>%
mutate(
count1 = (p_choice1 / 100) * n_choice1,
count2 = (p_choice2 / 100) * n_choice2,
count3 = (p_choice3 / 100) * n_choice3,
count4 = (p_choice4 / 100) * n_choice4
) %>%
select(party, starts_with("count")) %>%
pivot_longer(cols = starts_with("count"), names_to = "choice", values_to = "count") %>%
mutate(
choice = case_when(
choice == "count1" ~ "選択肢1",
choice == "count2" ~ "選択肢2",
choice == "count3" ~ "選択肢3",
choice == "count4" ~ "選択肢4"
),
choice = factor(choice, levels = c("選択肢4", "選択肢3", "選択肢2", "選択肢1")) # 積み上げ順序(1が上)
) %>%
# 政党内で各選択肢が占める割合 (%) を算出
group_by(party) %>%
mutate(percentage = (count / sum(count)) * 100) %>%
ungroup() %>%
mutate(party = factor(party, levels = c("自民", "公明", "維新", "野党", "支持なし")))
# 3. ANFフォーマット用の定数定義
AONF_CAPTION <- "Archives from 2026 Onward and Notes for the Future\n2026年以降の記録 | https://ab.cocolog-nifty.com/note/"
# 4. グラフの描画(政党別の自己責任意識)
ggplot(df_party_distribution, aes(x = party, y = percentage, fill = choice)) +
geom_bar(stat = "identity", width = 0.5, position = "stack") +
# 割合が3%以上の領域に数値を表示
geom_text(aes(label = if_else(percentage >= 3.0, paste0(round(percentage, 1), "%"), "")),
position = position_stack(vjust = 0.5), size = 3, color = "black") +
# 選択肢のグラデーション(見やすさ重視の配色)
scale_fill_brewer(palette = "YlGnBu", direction = 1) +
labs(
title = "政党別の自己責任意識(橋本氏の図表8・2dを改変)",
subtitle = "",
x = "支持政党など",
y = "政党内における選択肢の割合 (%)",
fill = "選択肢") +
theme_minimal(base_family = "HiraKakuProN-W3") +
theme(
legend.position = "bottom",
plot.caption = element_text(size = 8, hjust = 1, color = "gray30"),
plot.title = element_text(face = "bold", hjust = 0.5),
axis.text.x = element_text(size = 11, face = "bold")
)
```
## 3
```{r,out.width="100%",fig.asp=1}
library(FactoMineR)
library(ggplot2)
library(dplyr)
library(tidyr)
# 1. 元データから度数(人数)クロス表を復元
n_total <- 43820
shares_choice <- c(Choice1 = 0.051, Choice2 = 0.286, Choice3 = 0.493, Choice4 = 0.170)
n_choices <- n_total * shares_choice
p_matrix <- matrix(
c(28.6, 2.4, 13.8, 8.3, 47.0, # 選択肢1
25.0,2.7,11.8,7.2,53.2, # 選択肢2
16.6,2.4,9.2,8.7,63.0, # 選択肢3
14.0,2.0,9.5,12.5,62.0), # 選択肢4
byrow = TRUE, nrow = 4,
dimnames = list(c("選択肢1", "選択肢2", "選択肢3", "選択肢4"),
c("自民", "公明", "維新", "野党", "支持なし"))
)
cross_table <- as.data.frame(sweep(p_matrix, 1, n_choices / 100, "*"))
knitr::kable(cross_table,digits = 0)
w01 <- cross_table
rowSums(w01)
colSums(w01)
# 2. 対応分析 (CA) の実行
res_ca <- CA(cross_table, graph = FALSE)
# 3. プロット用データの抽出
df_rows <- as.data.frame(res_ca$row$coord[, 1:2]) %>%
rename(Dim1 = `Dim 1`, Dim2 = `Dim 2`) %>%
mutate(label = rownames(.), type = "選択肢")
df_cols <- as.data.frame(res_ca$col$coord[, 1:2]) %>%
rename(Dim1 = `Dim 1`, Dim2 = `Dim 2`) %>%
mutate(label = rownames(.), type = "政党・支持層")
df_biplot <- bind_rows(df_rows, df_cols)
contrib_dim1 <- round(res_ca$eig[1, 2], 1)
contrib_dim2 <- round(res_ca$eig[2, 2], 1)
# ANFフォーマット用の定数定義
AONF_CAPTION <- "Archives from 2026 Onward and Notes for the Future\n2026年以降の記録 | https://ab.cocolog-nifty.com/note/"
# 4. ggplot2 による描画(上限マージンと位置調整の適用)
ggplot(df_biplot, aes(x = Dim1, y = Dim2, color = type, shape = type)) +
geom_hline(yintercept = 0, linetype = "dashed", color = "gray60") +
geom_vline(xintercept = 0, linetype = "dashed", color = "gray60") +
geom_point(size = 4, stroke = 1) +
# vjustを少し大きめにするか、選択肢4だけ位置をずらす処理
geom_text(aes(label = label),
vjust = if_else(df_biplot$label == "選択肢4", 1.5, -0.8), # 選択肢4は点の下側に配置
fontface = "bold", show.legend = FALSE) +
scale_color_manual(values = c("選択肢" = "#1f77b4", "政党・支持層" = "#ff7f0e")) +
scale_shape_manual(values = c("選択肢" = 17, "政党・支持層" = 16)) +
labs(
title = "選択肢と支持政党の対応分析(バイプロット)",
x = paste0("第1軸 (Dim 1: ", contrib_dim1, "%)"),
y = paste0("第2軸 (Dim 2: ", contrib_dim2, "%)"),
color = "要素タイプ",
shape = "要素タイプ",
caption = AONF_CAPTION
) +
ylim(-0.08, 0.18) + # y軸の上限を広げて、枠外への見切れを防止
theme_minimal(base_family = "HiraKakuProN-W3") +
theme(
legend.position = "bottom",
plot.caption = element_text(size = 8, hjust = 1, color = "gray30"),
plot.title = element_text(face = "bold", hjust = 0.5),
axis.title = element_text(size = 10)
)
```
## 4
```{r,out.width="100%"}
library(vcd)
# 1. 度数(人数)クロス表(行列型)の復元
n_total <- 43820
shares_choice <- c(0.051, 0.286, 0.493, 0.170)
n_choices <- n_total * shares_choice
p_matrix <- matrix(
c(28.6, 2.4, 13.8, 8.3, 47.0, # 選択肢1
25.0,2.7,11.8,7.2,53.2, # 選択肢2
16.6,2.4,9.2,8.7,63.0, # 選択肢3
14.0,2.0,9.5,12.5,62.0), # 選択肢4
byrow = TRUE, nrow = 4,
dimnames = list(c("選択肢1", "選択肢2", "選択肢3", "選択肢4"),
c("自民", "公明", "維新", "野党", "支持なし"))
)
cross_table <- as.table(sweep(p_matrix, 1, n_choices / 100, "*"))
# 【重要】t() を用いて行列を転置し、「政党」をX軸(横)、「選択肢」をY軸(縦)に入れ替える
cross_table_flipped <- t(cross_table)
# 2. ANFフォーマット用の定数定義
AONF_CAPTION <- "Archives from 2026 Onward and Notes for the Future\n2026年以降の記録 | https://ab.cocolog-nifty.com/note/"
# 3. モザイクプロットの描画
mosaic(
cross_table_flipped,
shade = TRUE,
legend = TRUE,
direction = c("v", "h"), # 転置したデータに対して縦・横の順で分割
gp_labels = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 9),
gp_varnames = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 11, fontface = "bold"),
main = "政党別の選択肢分布(モザイクプロット)",
main_gp = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 14, fontface = "bold"), # タイトルの文字化け対策
pop = FALSE
)
# カレントなビューポートの最下部付近にANFキャプションを配置
grid.text(
AONF_CAPTION,
x = unit(0.95, "npc"),
y = unit(0.02, "npc"),
just = c("right", "bottom"),
gp = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 7.5, col = "gray30")
)
```
## 5
```{r,out.width="100%"}
library(vcd)
library(grid) # grid.text や unit を使用するために追加
# 1. 度数(人数)クロス表(行列型)の復元(選択肢ごとの全体比率から復元)
n_total <- 43820
shares_choice <- c(0.051, 0.286, 0.493, 0.170) # 選択肢1〜4の全体割合
n_choices <- n_total * shares_choice
p_matrix <- matrix(
c(28.6, 2.4, 13.8, 8.3, 47.0, # 選択肢1
25.0,2.7,11.8,7.2,53.2, # 選択肢2
16.6,2.4,9.2,8.7,63.0, # 選択肢3
14.0,2.0,9.5,12.5,62.0), # 選択肢4
byrow = TRUE, nrow = 4,
dimnames = list(c("選択肢1", "選択肢2", "選択肢3", "選択肢4"),
c("自民", "公明", "維新", "野党", "支持なし"))
)
# 行方向(MARGIN = 1)に各選択肢の人数規模を掛け合わせる
cross_table <- as.table(sweep(p_matrix, 1, n_choices / 100, "*"))
cross_table
# 2. ANFフォーマット用の定数定義
AONF_CAPTION <- "Archives from 2026 Onward and Notes for the Future\n2026年以降の記録 | https://ab.cocolog-nifty.com/note/"
# 3. 選択肢別モザイクプロットの描画
# 転置をせず cross_table をそのまま投入することで X軸=選択肢、Y軸=政党 となります
mosaic(
cross_table,
shade = TRUE,
legend = TRUE,
direction = c("v", "h"), # 選択肢を縦(横軸)に分割、政党を横(縦軸)に分割
gp_labels = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 9),
gp_varnames = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 11, fontface = "bold"),
main = "選択肢別の支持政党分布(モザイクプロット)",
main_gp = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 14, fontface = "bold"), # タイトルの文字化け対策
pop = FALSE
)
# カレントなビューポートの最下部付近にANFキャプションを配置
grid.text(
AONF_CAPTION,
x = unit(0.95, "npc"),
y = unit(0.02, "npc"),
just = c("right", "bottom"),
gp = gpar(fontfamily = "HiraKakuProN-W3", fontsize = 7.5, col = "gray30")
)
```