日本の経済投票-なぜ日本で政権交代が起こらないのか?(有斐閣, 2025年)

オンライン上の補遺

本書の構成

書影 オンライン上の補遺の目的

『日本の経済投票―なぜ日本で政権交代が起こらないのか?』についてのオンライン上での補遺です。本文には掲載できなかった分析の説明、補足の分析結果、分析のための統計ソフトウェアのコードなどを掲載しています。コードは主にRで使用するものですが、他にもStataやPythonのコードなども含まれています。参考になさってください。

本書の構成は以下の通りです。各章の付録には、画面左側のナビゲーションからも、随時移動してもらうことができます。

序章 日本の経済投票についての問い: 1

第1章 本書は何を明らかにするのか?(1)―データの素描からみる日本の経済投票: 16

第2章 経済評価はどのように動いてきたのか?: 38

第3章 経済評価は何によって動いてきたのか?: 51

第4章 政治的支持はどのように動いてきたのか?: 64

第5章 政治的支持は何によって動いてきたのか?: 74

補論:時系列データ分析について考える: 91

第6章 所得は経済評価、投票選択を決めるのか?―観察データの分析(1): 96

第7章 党派性、経済評価は投票選択を決めるのか?―観察データの分析(2): 115

補論:社会志向の経済評価と個人志向の経済評価-「個人志向の経済評価のレンズ」を考える: 130

第8章 経済情報をどのように受け取っているのか?―実験データの分析(1): 134

第9章 経済情報をどのように推論・表明しているのか?―実験データの分析(2): 166

第10章 日本の経済投票はどのようなものなのか?―実験データの分析(3): 194

終章 日本の経済投票についての答え: 207

本書を補完する文献について

本書の中では、文献的背景の詳述は行いませんでした。本書の内容に関連する文献のレビューについては、以下のものを参照してください。

また第8章の実験8-1、第9章の実験9-1、実験9-2は関連する研究を行っています。その追試として、本書の実験を行い、分析結果を示しました。元の分析は下記については、下記を参照してください。

以降の分析で利用するソフトウェアRとR packagesの一覧

本書の分析では、多くの場合に、統計ソフトウェアRを利用した分析を行いました。Rでは、分析に必要なパッケージを使いながら分析をすることが多いです。本書で利用したRのパッケージ、そのバージョン、利用目的を以下に示しました。

#-------------------
# Software version
#-------------------
# R version 4.4.2 (2025-03-20)

#-------------------
# Package versions
#-------------------
library(broom) #Ver.1.0.7 データの成形に利用
library(cjoint) #Ver2.1.1 コンジョイント実験のデータ分析に利用
library(data.table) #Ver.1.16.4 データフレームの成形に利用
library(dtw) #Ver.1.23-1 時系列データのクラスター分析に利用
library(ebal) #Ver.0.1-8 データへの加重の付与で利用
library(emmeans) #Ver.1.10.7 コンジョイント実験のデータ分析に利用
library(fracdiff) #Ver.1.5-3 実数和分分析に利用
library(ggfortify) #Ver.0.4.17 各種図の効果的な描画のために利用
library(ggpubr) #Ver.0.6.0 図内の統計的有意差の描画のために利用
library(ggrepel) #Ver.0.9.6 各種図の効果的な描画のために利用
library(ggsignif) #Ver.0.6.4 図内の統計的有意差の描画のために利用
library(gridExtra) #Ver.2.3 複数図を並べて配 置する際の調整に利用
library(gtable)  #Ver.0.3.6 表の作成に利用
library(kableExtra) #Ver.1.4.0 本webページにおいて各種の表を作成・表示するために利用
library(knitr) #Ver.1.49 このwebページをRを介して作成するために利用
library(LSX) #Ver.1.4.2 テキスト分析に利用
library(magrittr) #Ver.2.0.3 データの成形に利用
library(MASS) #Ver.7.3-65 平均値の差の計算で利用
library(psych) #Ver.2.4.12 記述統計に利用
library(purrr) #Ver.1.0.4 コードの反復処理などに利用
library(quanteda) #Ver.4.2.0 テキスト分析に利用
library(quanteda.textstats) #Ver.0.97.2 テキスト分析に利用
library(readtext) #Ver.0.91 テキスト分析に利用
library(reticulate) #Ver.1.40 テキスト分析時にPythonとの連携で利用
library(Rmisc) #Ver1.5.1 グループごとの平均値などの計算に利用
library(scales) #Ver.1.3.0 変数の正規化に利用
library(showtext) #Ver.0.9-7 図のフォント設定のために利用
library(stats) #Ver.4.4.2 平均値の差に関する検定で利用
library(stringr) #Ver.1.5.1 データの成形時に利用
library(sysfonts) #Ver.0.8.9 図のフォント設定のために利用
library(tidyverse) #Ver.2.00 データの成形時に利用
library(TSclust) #Ver.1.3.1 時系列データのクラスター分析で利用
library(tseries) #Ver.0.10-58 時系列データ分析で利用
library(vtable) #Ver.1.4.8 バランス・チェックに利用
library(WeightIt) #Ver.1.4.0 データへの加重の付与で利用
library(Zelig) #Ver.5.1.7 シミュレーション分析で利用
library(ZeligChoice) #Ver.09-6 シミュレーション分析で利用
library(zoo) #Ver.1.8-12 時系列データ分析で利用

第1章:本章は何を明らかにするのか?

本文の補足分析と各図表のコード

第1章で示した各図のRコードを下記に挙げる。分析の追試・再現にご利用いただきたい。但し、データに関しては共有が難しいものが多いことから、必要に応じて、筆者にご連絡いただきたい。

図1-1:時事データをもとにした景気評価の推移

図1-2:時事データをもとにした暮らし向き評価の推移

#----------------------------
# 関数の読み込み(plot1_1.R)
#----------------------------

source("plot1_1.R") #図1-4のコードも参照

#------------------
# データの読み込み
#------------------

dat1_1 <- read.csv("approve_economy.csv", fileEncoding = "SJIS") %>%
  mutate(
    sociotropic_gd = q5c1 + q5c2,
    sociotropic_bd = q5c4 + q5c5,
    liv_gd         = q3c1 + q3c2,
    liv_bd         = q3c4 + q3c5
  )

df_keiki <- dat1_1 %>%
  select(yearmon, year_graph, sociotropic_gd, sociotropic_bd)

df_kurashi <- dat1_1 %>%
  select(yearmon, year_graph, liv_gd, liv_bd)

#------------------
#  プロットの作成
#------------------

a1_1 <- plot1_1(df_keiki, "sociotropic_bd", "sociotropic_gd", "景気への評価(-)", "景気への評価(+)")
a1_2 <- plot1_1(df_kurashi, "liv_bd", "liv_gd", "暮らし向きへの評価(-)", "暮らし向きへの評価(+)")


grid.arrange(a1_1[[1]], a1_1[[2]], a1_1[[3]], ncol = 3, widths = c(4/9, 1/9, 4/9))
grid.arrange(a1_2[[1]], a1_2[[2]], a1_2[[3]], ncol = 3, widths = c(4/9, 1/9, 4/9))

図1-3:JESデータをもとにした景気評価の推移

【補足】JESデータをもとにした暮らし向き評価の推移

以下では、本文で掲載のなかった「暮らし向き評価」についての図も掲載する。

なお本文で言及できなかった点を、下記に断る。

・ 2012年については、衆議院選挙後・全国インターネット調査のデータを用いた。同年については、選挙後調査において経済評価データが含まれているためである。

・ 2013年については、参院選事前インターネット調査のデータを用いた。

・ 2014年については、衆院選事前インターネット調査のデータを用いた。

・ 2016年については、参院選事前郵送調査のデータを用いた。

#---------------------------
# 関数の読み込み(plot1_3.R)
#---------------------------

source("plot1_3.R")

#------------------
# データの読み込み
#------------------

dat1_3 <- read.csv("df_ec_keiki.csv") %>%
  mutate(否定 = 否定*100,
         肯定 = 肯定*100)
  
#----------------
# プロットの作成
#----------------

a1_3 <- plot1_3(dat1_3, "景気への評価(-)", "景気への評価(+)")

grid.arrange(a1_3[[1]], a1_3[[2]], a1_3[[3]], ncol = 3, widths = c(4/9, 1/9, 4/9))
#景気評価に関する図は出力を省略。

図1-4:日本の有権者の与党支持率、野党支持率、無党派層の割合の推移

#------------------
# データの読み込み
#------------------

dat1_4 <- read_csv("approve_economy.csv", locale = locale(encoding = "SJIS")) %>%
  dplyr::select(yearmon, year_graph, ruling, opposite, indep)
#(上述の"approve_economy.csv"データに依拠、データの閲覧・入手については筆者にご相談ください)

#---------------------------------------
# プロットの作成(plot1_1.Rの内部も参照)
#---------------------------------------

a.mid<-ggplot(dat1_4,aes(x=1,y=year_graph))+
  geom_text(aes(label=year_graph))+
  geom_segment(aes(x=0.94,xend=0.96,yend=year_graph))+
  geom_segment(aes(x=1.04,xend=1.065,yend=year_graph))+
  ggtitle("")+
  ylab(NULL)+
  theme(axis.title=element_blank(),
        panel.grid=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        panel.background=element_blank(),
        axis.text.x=element_text(color=NA),
        axis.ticks.x=element_line(color=NA),
        plot.margin = unit(c(1,-1,1,-1), "mm")) +
  scale_x_reverse()


a1 <- ggplot(data = dat1_4, aes(x = as.Date(yearmon,"%Y-%m-%d"), y = ruling)) +
  geom_bar(stat = "identity") +  ggtitle("与党支持率") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(), 
        plot.margin = unit(c(1,-1,1,0), "mm")) +
  coord_flip()+
  ylim(0, 75)+
  xlab("年")+
  ylab("与党支持率")+
  theme(text = element_text(family = "jpfont"))+
  theme_bw()


a2 <- ggplot(data = dat1_4, aes(x = as.Date(yearmon,"%Y-%m-%d"), y = opposite)) +
  geom_bar(stat = "identity") + ggtitle("野党支持率") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(), 
        plot.margin = unit(c(1,-1,1,0), "mm")) +
  coord_flip()+
  ylim(0, 75)+
  xlab("年")+
  ylab("野党支持率")+
  theme(text = element_text(family = "jpfont"))+
    theme_bw()


a3 <- ggplot(data = dat1_4, aes(x = as.Date(yearmon,"%Y-%m-%d"), y = indep)) +
  geom_bar(stat = "identity") + ggtitle("無党派層割合") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(), 
        plot.margin = unit(c(1,-1,1,0), "mm")) +
  coord_flip()+
  xlab("年")+
  ylab("無党派割合")+
  ylim(0, 75)+
  theme(text = element_text(family = "jpfont"))+
    theme_bw()


aa1 <- ggplot_gtable(ggplot_build(a1))
aa2 <- ggplot_gtable(ggplot_build(a2))
aa3 <- ggplot_gtable(ggplot_build(a3))

aa.mid <- ggplot_gtable(ggplot_build(a.mid))

grid.arrange(aa1,aa.mid,aa2,aa.mid,aa3,ncol=5,widths=c(4/14,1/14,4/14,1/14,4/14))

図1-5:支持政党への残留と支持政党からの移動

#------------------
# データの読み込み
#------------------

dat1_5 <- read_csv("psupport_move.csv")

#------------
# 要件の設定
#------------

dat1_5 <- dat1_5 %>%
  mutate(Condition = factor(Condition, levels = c("残留: 与党→与党", "残留: 野党→野党", 
                                                  "離脱: 与党→野党", "離脱: 野党→与党")))

#----------------
# プロットの作成
#----------------

ggplot(dat1_5, aes(x = 年, y = Ratio * 100, fill = Condition)) +
  geom_bar(stat = "identity", position = position_dodge(), color = "black") +
  geom_text(aes(label = sprintf("%.1f", Ratio * 100)), 
            position = position_dodge(width = 0.9), 
            vjust = -0.5, size = 4, color = "black") +
  facet_wrap(~Condition, ncol = 2) +
  scale_fill_grey(start = 0.5, end = 0.8) + 
  labs(title = "", x = "年", y = "割合(%) ") +
  theme_bw(base_size = 14) +
  theme(
    legend.position = "none", 
    panel.grid.major = element_line(size = 0.5),
    panel.grid.minor = element_blank(),
    strip.text = element_text(face = "bold", size = 12) 
  ) +
  geom_label(aes(label = sprintf("%.1f", Ratio * 100)), 
             position = position_dodge(width = 0.9), 
             vjust = -0.5, size = 4, fill = "white", color = "black", label.size = 0.3, 
             label.padding = unit(0.2, "lines"))

dat1_5作成のためのコードの詳細については、筆者にお問い合わせください。例は次の通り。

#------------------
# データの読み込み
#------------------

jes2019 <- read_csv("2019jes.csv", locale = locale(encoding = "SJIS"))

#-------------------------------
# 「与党―与党」のダミー変数作成
#-------------------------------

jes2019 <- jes2019 %>%
  mutate(
    rul_rul_dum2019 = case_when(
      (Q2 %in% c("自民党", "公明党")) & (aQ7 %in% c("自民党", "公明党")) ~ 1,
      TRUE ~ 0
    )
  )

#-------------------------------
# 「与党―野党」のダミー変数作成
#-------------------------------

jes2019 <- jes2019 %>%
  mutate(
    rul_op_dum2019 = case_when(
      (aQ7 %in% c("自民党", "公明党")) &
      (Q2 %in% c("立憲民主", "社民党", "共産党", "次世代の", "みんなの",
                 "希望の党", "新党改革", "日本未来の党", "日本維新", "その他")) ~ 1,
      TRUE ~ 0
    )
  )

【補足】政党支持と投票選択間のすべての組み合わせを使った分析

第1章・本文では、政党支持と投票の組み合わせのうち、一部のみを図示した。組み合わせのすべてを含めて、残留と離脱の流れを表す図を以下に示す。以下の図からは、与党支持者の多くがそのまま与党投票に残存していることが見てとれる。政党支持から投票への流動性は、どちらかというと野党支持者に認められるようである。

図1-6: 党派別の社会志向の経済評価

library(tidyverse)

#------------------
# データの読み込み
#------------------

dat1_6 <- read_csv("df_temp.csv", locale = locale(encoding = "SJIS"))

#---- 与党派:社会志向(+)
dat1_6_1 <- dat1_6 %>%
  select(yearmon, sociotropic_gd_rul, sociotropic_bd_rul) %>%
  mutate(政党支持 = "与党派")

#---- 野党派:社会志向(+)
dat1_6_2 <- dat1_6 %>%
  select(yearmon, sociotropic_gd_op, sociotropic_bd_op) %>%
  mutate(政党支持 = "野党派")

#---- 無党派:社会志向(+)
dat1_6_3 <- dat1_6 %>%
  select(yearmon, sociotropic_gd_indep, sociotropic_bd_indep) %>%
  mutate(政党支持 = "無党派")

colnames(dat1_6_1) <- colnames(dat1_6_2) <- colnames(dat1_6_3) <- c("年", "肯定", "否定", "政党支持")
dat1_6 <- bind_rows(dat1_6_1, dat1_6_2, dat1_6_3) %>%
  mutate(across(c(肯定, 否定), ~ . * 100))

dat1_6 <- dat1_6 %>%
  pivot_longer(cols = c(肯定, 否定), names_to = "景気評価", values_to = "値") %>%
  mutate(政党支持 = factor(政党支持, levels = c("与党派", "野党派", "無党派")))

#------------------
# プロットの作成
#------------------

ggplot(data = dat1_6, aes(x = as.Date(年,"%Y-%m-%d"), y = 値)) +
  geom_line(aes(color = 景気評価), size = 1) +
  scale_color_manual(values = c("grey", "black")) +
  xlab("年")+
  facet_wrap(~政党支持,ncol=1)+
  ylab("割合(%)")+ 
  theme_bw()+
theme(text = element_text(family = "jpfont"))

図1-7:党派別の景気評価の肯定的/否定的回答の割合

#----------------------------
# 関数の読み込み(plot1_7.R)
#----------------------------

source("plot1_7.R")

#------------------------------------------------
# データの読み込みとプロットの作成: 社会志向評価
#------------------------------------------------

dat1_7socio <- read.csv("df_ec_partisan.csv")
a1_7socio <- plot1_7(dat1_7socio, "景気評価", "景気")


grid.arrange(a1_7socio$g1,  a1_7socio$g2, 
              a1_7socio$g3, 
             ncol = 3, widths = c(1/3, 1/3, 1/3))

【補足】党派別の暮らし向き評価の肯定的/否定的回答の割合

図1-10:与党支持率と内閣支持率の関係に関するローリング回帰分析

以下、図1-10のコードはPythonによるものである。本文においては、与党支持率内閣支持率の関係と社会志向の肯定的経済評価と内閣支持率の関係についてのローリング回帰分析の結果を報告した。以下では、下記の結果について分析結果を報告する。

①個人志向の肯定的な経済評価と内閣支持率の関係

②社会志向の否定的な経済評価と内閣不支持率の関係

③個人志向の否定的な経済評価と内閣不支持率の関係

④野党支持率と内閣不支持率の関係

#------------------
# モジュールの導入
#------------------


import statsmodels.api as sm
import pandas

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import pandas_datareader as pdr
from statsmodels.regression.rolling import RollingOLS
import matplotlib.pyplot as plt
import seaborn
seaborn.set_style('darkgrid')
pd.plotting.register_matplotlib_converters()
%matplotlib inline


#------------------
# データの読み込み
#------------------

df = pd.read_csv('df_fecm.csv',
                  index_col='yearmon', parse_dates=True,encoding='cp932')
print(df)

#------------------
# 内生変数の設定
#------------------

endog = df.approve
endog

#---------------------------------------
# 外生変数の設定:社会志向の経済評価(+)
#---------------------------------------

exog = sm.add_constant(df['ruling'])

#----------------------
# 推定と推定結果の確認
#----------------------

rols_ruling = RollingOLS(endog, exog, window=60)
rres_ruling = rols_ruling.fit()
params = rres_ruling.params
print(params.head())
print(params.tail())

#------------------
# プロットの作成
#------------------

fig_ruling= rres_dis_liv.plot_recursive_coefficient(variables=['ruling'], figsize=(14,6))

【補足】個人志向の肯定的経済評価と内閣支持率の関係に関するローリング回帰分析

【補足】社会志向の否定的経済評価と内閣不支持率の関係に関するローリング回帰分析

【補足】個人志向の否定的経済評価と内閣不支持率の関係に関するローリング回帰分析

【補足】野党支持率と内閣不支持率の関係に関するローリング回帰分析

第2章:経済評価はどのように動いてきたのか?

利用するデータの記述統計

第2章で利用する時事データの記述統計は、以下のとおりである。

時事データの記述統計

統計量
平均 標準偏差 最小値 最大値 歪度 尖度
社会志向(+) 8.187 5.071 0.0 28.4 0.759 0.136
社会志向(-) 32.732 14.171 0.0 86.0 0.702 0.003
個人志向(+) 5.137 2.574 0.0 15.2 1.472 2.081
個人志向(-) 35.353 10.548 0.0 74.1 0.475 1.125
与党支持率 28.981 5.961 5.9 43.6 -0.992 2.401
野党支持率 16.902 5.935 4.7 33.9 -0.167 -0.872
無党派割合 49.045 11.190 18.6 71.4 -0.627 -0.187
内閣支持率 36.689 11.223 4.4 78.4 0.123 0.302
内閣不支持率 36.990 12.262 6.0 83.7 0.653 0.584

本文の補足分析と各図表のコード

図2-2:時事データの経済質問における回答割合の推移

#---------------------------
# 関数の読み込み(plot2_2.R)
#---------------------------
source("plot2_2.R")

#------------------
# データの読み込み
#------------------
dat2_2 <- read.csv("approve_economy.csv", fileEncoding = "SJIS")


# 暮らし向き
cols1 <- c("q3c1", "q3c2", "q3c3", "q3c4", "q3c5", "q3c6")
labels1 <- c("大変楽になった", "やや楽になった", "どちらでもない", "やや苦しくなった", "大変苦しくなった", "わからない")
b2_2_1 <- plot2_1(dat2_2, cols1, labels1, "暮らし向き")

# 物価
cols2 <- c("q4c3", "q4c1", "q4c2", "q4c4")
labels2 <- c("今より下がると思う", "落ち着いてきたと思う", "上がると思う", "わからない")
b2_2_2 <- plot2_1(dat2_2, cols2, labels2, "物価")

# 景気
cols3 <- c("q5c1", "q5c2", "q5c3", "q5c4", "q5c5", "q5c6")
labels3 <- c("確かに良くなってきたと思う", "やや良くなってきたと思う", "どちらでもない", "やや悪くなってきたと思う", "確かに悪くなってきたと思う", "わからない")
b2_2_3 <- plot2_1(dat2_2, cols3, labels3, "景気")

# これから先の生活
cols4 <- c("q6c1", "q6c2", "q6c3", "q6c4")
labels4 <- c("良くなっていく", "変わりない", "悪くなっていく", "どちらともいえない")
b2_2_4 <- plot2_1(dat2_2, cols4, labels4, "これから先の生活")

#------------------
# プロットの作成
#------------------

gridExtra::grid.arrange(b2_2_1, b2_2_2, b2_2_3, b2_2_4, ncol = 2, nrow = 2)

表2-2:2 種類の経済評価に関する実数和分分析の結果

#------------------
# データの読み込み
#------------------

dat2_2 <- read.csv("approve_economy.csv", fileEncoding = "SJIS")


#--------------------------------- 
# FIの計算:社会志向の経済評価(+)
#--------------------------------- 

fdGPH(na.omit(sociotropic_gd))

#--------------------------------- 
# FIの計算:社会志向の経済評価(-)
#--------------------------------- 

fdGPH(na.omit(sociotropic_bd))

#--------------------------------- 
# FIの計算:個人志向の経済評価(+)
#--------------------------------- 

fdGPH(na.omit(liv_gd))

#--------------------------------- 
# FIの計算:個人志向の経済評価(-)
#--------------------------------- 

fdGPH(na.omit(liv_bd))

【補足】2種類の経済評価変数についてのAugmented Dickey-Fuller testとKPSS testの結果

#---------------- 
# 関数の読み込み
#----------------
source("adf_kpss_test.R")


#------------------------
# データの読み込みと設定
#------------------------ 
dat2_2 <- read.csv("approve_economy.csv", fileEncoding = "SJIS")

vars <- dat2_2 %>%
  dplyr::select(sociotropic_gd, sociotropic_bd, liv_gd, liv_bd) %>%
  as.list() %>%
  setNames(c("社会志向(+)", "社会志向(-)", "個人志向(+)", "個人志向(-)"))


#---------------- 
# 分析結果の表化
#----------------
df_results <- map_dfr(
  names(vars),
  ~ adf_kpss_test(vars[[.x]]) %>%
    mutate(変数名 = .x)   
) %>%
  select(変数名, everything())  

#----------- 
# 表の出力
#----------- 
tb2_2 <- df_results %>%
  kbl(
    format = "html",
    digits = 4,                     
  ) %>%
  kable_styling(full_width = FALSE)

ADF & KPSS 検定結果一覧

変数名 ADF statistic ADF p-value KPSS statistic KPSS p-value
社会志向(+) -5.3640 0.0100 1.3673 0.01
社会志向(-) -4.5883 0.0100 0.1490 0.10
個人志向(+) -3.7478 0.0216 4.2473 0.01
個人志向(-) -4.1487 0.0100 2.8732 0.01

図2-3:2種類の経済評価と政治経済的出来事の関係

#---------------------------- 
# 関数の読み込み(plot2_3.R)
#---------------------------- 
source(plot2_3.R)

#------------------
# データの読み込み
#------------------
dat2_3 <- read.csv("approve_economy.csv", fileEncoding = "SJIS") %>%
  mutate(
    sociotropic_gd = q5c1 + q5c2,
    sociotropic_bd = q5c4 + q5c5,
    liv_gd         = q3c1 + q3c2,
    liv_bd         = q3c4 + q3c5
  )

#---------------- 
# イベントの設定
#----------------
events <- tibble(
  date = as.Date(c("1973-10-01", "1989-04-01", "1990-01-01", "1997-07-01", 
                   "2008-09-01", "2011-03-01", "2012-12-01", "2020-04-01")),
  label = c("第1次石油ショック(1973)", "消費税導入(1989)", "バブル経済崩壊(1990)",
            "アジア通貨危機(1997)", "グローバル経済危機(2008)", "東日本大震災(2011)",
            "アベノミクス導入(2012)", "緊急事態宣言(2020)")
)

#-------------- 
# データの整形
#--------------
dat2_3keiki <- dat2_3 %>%
  select(yearmon, sociotropic_gd, sociotropic_bd) %>%
  pivot_longer(cols = -yearmon, names_to = "経済評価", values_to = "value") %>%
  mutate(経済評価 = recode(経済評価, sociotropic_gd = "肯定", sociotropic_bd = "否定"))

dat2_3kurashi <- dat2_3 %>%
  select(yearmon, liv_gd, liv_bd) %>%
  pivot_longer(cols = -yearmon, names_to = "経済評価", values_to = "value") %>%
  mutate(経済評価 = recode(経済評価, liv_gd = "肯定", liv_bd = "否定"))

#-----------------
# プロットの作成
#-----------------
b1 <- plot2_3(dat2_3keiki , "A:社会志向の経済評価の推移と政治経済的出来事", 45)
b2 <- plot2_3(dat2_3kurashi, "B:個人志向の経済評価の推移と政治経済的出来事", 28)

windows(30, 20)
grid.arrange(b1, b2, nrow = 2)

図2-4:2種類の経済評価と景気循環の関係

#---------------------------- 
# 関数の読み込み(plot2_4.R)
#---------------------------- 
source("plot2_4.R")

#------------------
# データの読み込み
#------------------
dat2_4 <- read.csv("approve_economy.csv", fileEncoding = "SJIS") %>%
  mutate(
    sociotropic_gd = q5c1 + q5c2,
    sociotropic_bd = q5c4 + q5c5,
    liv_gd         = q3c1 + q3c2,
    liv_bd         = q3c4 + q3c5
  )

#---------------------------- 
# 景気循環のセグメントを定義
#----------------------------
business_cycles <- data.frame(
  start = as.Date(c("1963-12-01", "1965-10-01", "1971-12-01", "1975-03-01",
                    "1977-10-01", "1983-02-01", "1986-11-01", "1993-10-01",
                    "1999-12-01", "2002-01-01", "2009-03-01", "2012-11-01")),
  end = as.Date(c("1964-10-01", "1970-07-01", "1973-11-01", "1977-01-01",
                  "1980-02-01", "1985-06-01", "1991-02-01", "1997-05-01",
                  "2000-11-01", "2008-02-01", "2012-03-01", "2020-05-01"))
)



#----------------
# プロットの作成
#----------------
b1 <- plot2_4(dat2_4, "sociotropic_gd", "sociotropic_bd", 
              "A: 社会志向の経済評価の推移と景気循環", 48, "社会志向の経済評価")

b2 <- plot2_4(dat2_4, "liv_gd", "liv_bd", 
              "B: 個人志向の経済評価の推移と景気循環", 18, "個人志向の経済評価")

windows(width = 240, height = 180)
grid.arrange(b1, b2, nrow = 2)

表2-3:党派別の社会志向の否定的経済評価・党派性差異の記述統計

本文に掲載した否定的な社会志向の経済評価の党派別データの記述統計のコードは以下のとおりである。

#------------------ 
# データの読み込み
#------------------
dat2_3 <- read_csv("approve_economy.csv", locale = locale(encoding = "SJIS")) %>%
  mutate(
    与党派_社会志向_否定 = sociotropic_bd_rul,
    野党派_社会志向_否定 = sociotropic_bd_op,
    無党派_社会志向_否定 = sociotropic_bd_indep,
    与野党派間差異 = sociotropic_bd_rul - sociotropic_bd_op,
    与無党派間差異 = sociotropic_bd_rul - sociotropic_bd_indep,
    野無党派間差異 = sociotropic_bd_op - sociotropic_bd_indep
  ) %>%
  select(与党派_社会志向_否定, 野党派_社会志向_否定, 無党派_社会志向_否定, 
         与野党派間差異, 与無党派間差異, 野無党派間差異)

#----------------
# 記述統計の抽出
#----------------
stats <- dat2_3 %>%
  describe() %>%
  select(mean, sd, min, max, skew, kurtosis) %>%
  rename(平均 = mean, 標準偏差 = sd, 最小値 = min, 最大値 = max, 歪度 = skew, 尖度 = kurtosis)

#---------- 
# 表の作成
#---------- 
stats %>%
  knitr::kable(
    format = "html",
    booktabs = TRUE, 
    caption = "党派別の社会志向の肯定的経済評価・党派性差異の記述統計",
    digits = 3
  ) %>%
  add_header_above(header = c(" " = 1, "統計量" = 6)) %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE)

【補足】党派別の社会志向の肯定的経済評価・党派性差異の記述統計

党派別の社会志向の肯定的経済評価・党派性差異の記述統計

統計量
平均 標準偏差 最小値 最大値 歪度 尖度
与党派・社会志向(+) 0.085 0.057 0.002 0.262 0.626 -0.302
野党派・社会志向(+) 0.070 0.068 0.000 0.401 1.923 4.358
無党派・社会志向(+) 0.056 0.032 0.003 0.160 0.715 0.119
与野党派間差異 0.015 0.061 -0.267 0.166 -1.497 4.289
与無党派間差異 0.029 0.035 -0.036 0.194 0.937 1.651
野無党派間差異 0.014 0.058 -0.071 0.307 2.221 5.610

【補足】党派別の個人志向の肯定的経済評価・党派性差異の記述統計

党派別個人会志向の肯定的経済評価・党派性差異の記述統計

統計量
平均 標準偏差 最小値 最大値 歪度 尖度
与党派・個人志向(+) 0.049 0.027 0.000 0.197 0.759 2.262
野党派・個人志向(+) 0.040 0.045 0.000 0.360 3.310 13.731
無党派・個人志向(+) 0.314 0.077 0.171 0.550 0.575 0.047
与野党派間差異 0.009 0.052 -0.339 0.175 -2.503 10.662
与無党派間差異 -0.265 0.090 -0.531 -0.084 -0.411 -0.161
野無党派間差異 -0.274 0.098 -0.543 0.005 -0.034 0.000

【補足】党派別の個人志向の否定的経済評価・党派性差異の記述統計

党派別の個人志向の否定的経済評価・党派性差異の記述統計

統計量
平均 標準偏差 最小値 最大値 歪度 尖度
与党派・個人志向(-) 0.313 0.109 0.100 0.677 0.566 0.039
野党派・個人志向(-) 0.035 0.010 0.012 0.060 -0.089 -0.635
無党派・個人志向(-) 0.323 0.160 0.000 1.000 1.105 3.891
与野党派間差異 0.278 0.114 0.066 0.656 0.566 -0.034
与無党派間差異 -0.010 0.169 -0.677 0.627 0.323 3.560
野無党派間差異 -0.288 0.162 -0.987 0.060 -1.116 3.808

表2-4:党派別の経済評価に関する実数和分分析の結果

#-----------------
# データの読み込み
#-----------------
dat2_4 <- read_csv("approve_economy.csv", locale = locale(encoding = "SJIS"))

#-------------------
# データリストの作成
#-------------------
dat2_4 <- list(
  dat$sociotropic_gd_rul, dat$sociotropic_gd_op, dat$sociotropic_gd_indep,
  dat$sociotropic_bd_rul, dat$sociotropic_bd_op, dat$sociotropic_bd_indep,
  dat$egotropic_gd_rul,   dat$egotropic_gd_op,   dat$egotropic_gd_indep,
  dat$egotropic_bd_rul,   dat$egotropic_bd_op,   dat$egotropic_bd_indep
)

labels <- c(
  "与党派・社会志向(+)", "野党派・社会志向(+)", "無党派・社会志向(+)",
  "与党派・社会志向(-)", "野党派・社会志向(-)", "無党派・社会志向(-)",
  "与党派・個人志向(+)", "野党派・個人志向(+)", "無党派・個人志向(+)",
  "与党派・個人志向(-)", "野党派・個人志向(-)", "無党派・個人志向(-)"
)

#----------
# FIの計算
#----------
results2_4 <- lapply(data_list2_4, function(data) {
  res <- fdGPH(na.omit(data))
  c(round(res$d, 3), round(res$sd.reg, 3))
})


#------------
# 結果の表化
#------------
results_df2_4 <- results %>%
  do.call(rbind, .) %>%
  as.data.frame() %>%
  setNames(c("d", "sd.reg")) %>%
  mutate(Variable = labels) %>%
  select(Variable, everything())

【補足】党派別の経済評価変数についてのAugmented Dickey-Fuller testとKPSS testの結果

#-----------------
# データの読み込み
#-----------------
data_list2_4 <- read_csv("approve_economy.csv", locale = locale(encoding = "SJIS")) %>%
  select(
    sociotropic_gd_rul, sociotropic_gd_op, sociotropic_gd_indep,
    sociotropic_bd_rul, sociotropic_bd_op, sociotropic_bd_indep,
    egotropic_gd_rul,   egotropic_gd_op,   egotropic_gd_indep,
    egotropic_bd_rul,   egotropic_bd_op,   egotropic_bd_indep
  ) %>%
  as.list()

#----------------------
#各変数に対応するラベル
#----------------------
labels <- c(
  "与党派・社会志向(+)", "野党派・社会志向(+)", "無党派・社会志向(+)",
  "与党派・社会志向(-)", "野党派・社会志向(-)", "無党派・社会志向(-)",
  "与党派・個人志向(+)", "野党派・個人志向(+)", "無党派・個人志向(+)",
  "与党派・個人志向(-)", "野党派・個人志向(-)", "無党派・個人志向(-)"
)

#----------------
# 分析結果の表化
#----------------
df_results2_4 <- map2_dfr(data_list2_4, labels, ~{
  series <- na.omit(.x)       
  
  # ADF 検定
  adf_res <- adf.test(series)
  adf_stat <- round(adf_res$statistic, 3)
  adf_pval <- round(adf_res$p.value, 4)
  
  # KPSS 検定
  kpss_res <- kpss.test(series, null = "Level")
  kpss_stat <- round(kpss_res$statistic, 3)
  kpss_pval <- round(kpss_res$p.value, 4)
  
  tibble(
    変数名  = .y,         
    ADF_Stat  = adf_stat,
    ADF_pval  = adf_pval,
    KPSS_Stat = kpss_stat,
    KPSS_pval = kpss_pval
  )
})

#----------
# 表の出力
#----------
tb2_4 <- df_results2_4 %>%
  kbl(
    format = "html",
    digits = 3
  ) %>%
  kable_styling(full_width = FALSE)

ADF&KPSS検定の結果

変数名 ADF_Stat ADF_pval KPSS_Stat KPSS_pval
与党派・社会志向(+) -2.888 0.202 0.225 0.100
野党派・社会志向(+) -4.424 0.010 0.200 0.100
無党派・社会志向(+) -3.042 0.137 0.155 0.100
与党派・社会志向(-) -2.521 0.356 0.202 0.100
野党派・社会志向(-) -2.594 0.326 0.209 0.100
無党派・社会志向(-) -2.237 0.476 0.195 0.100
与党派・個人志向(+) -3.274 0.076 0.652 0.018
野党派・個人志向(+) -5.832 0.010 0.974 0.010
無党派・個人志向(+) -2.536 0.350 2.074 0.010
与党派・個人志向(-) -3.012 0.150 2.232 0.010
野党派・個人志向(-) -2.503 0.364 0.541 0.032
無党派・個人志向(-) -5.256 0.010 2.216 0.010

図2-5:党派性と社会志向の肯定的経済評価

#------------------ 
# 関数の読み込み
#------------------
source("plot2_5df.R")
source("plot2_5_1.R")
source("plot2_5_2.R")


#------------------ 
# データの読み込み
#------------------
dat2_5 <- read.csv("approve_economy.csv", fileEncoding = "SJIS")
attach(dat2_5)
year <- read.csv("year.csv")
attach(year)


#------------------ 
# ハイライトの設定
#------------------
admin <- data.frame(
  start = as.Date( '2009-09-01'), 
  end   = as.Date('2012-11-01'))


#------------------ 
# プロットの作成
#------------------
#---- 社会志向 (+):原系列
df_parec1 <- plot2_5df(year$yearmon, cbind(sociotropic_gd_rul, sociotropic_gd_op), c("年", "与党派", "野党派"))
b1 <- plot2_5_1(df_parec1, "A:党派別の社会志向の経済評価(+)","年", "value", "党派別経済効果")

#---- 社会志向 (+): 差異
socposdiff = sociotropic_gd_rul-sociotropic_gd_op
df_parec2 <- create_dataframe(year$yearmon, socposdiff, c("年", "党派性差異"))
b2 <- plot2_5_2(df_parec2, "B:党派別の社会志向の党派性差異(+)", "党派性差異", "value")


grid.arrange(b1, b2, ncol = 1)

図2-6:党派性と社会志向の否定的経済評価

#------------------ 
# プロットの作成
#------------------
#---- 社会志向 (-):2系列併記
df_parec3 <- plot2_5df(year$yearmon, cbind(sociotropic_bd_rul, sociotropic_bd_op), c("年", "与党派", "野党派"))
b3 <- plot2_5_1(df_parec3, "A:党派別の社会志向の経済評価(-)","年", "value", "党派別経済効果")

#---- 社会志向 (-): 差異
socnegdiff = sociotropic_bd_rul-sociotropic_bd_op
df_parec4 <- plot2_5df(year$yearmon, socnegdiff, c("年", "党派性差異"))
b4 <- plot2_5_2(df_parec4, "B:党派別の社会志向の党派性差異(-)", "党派性差異", "value")


grid.arrange(b3, b4, ncol = 1)

【補足】党派性と個人志向の肯定的経済評価

第3章:経済評価は何によって動いてきたのか?

【補足】推定方法についての説明

なぜ実数和分誤差修正メカニズムなのか?

本書・第1章でも述べたように、政治学は、多くの時系列データの分析手法を導入してきた。なかでも政治学者が好んだ推定方法が、誤差修正モデル(Error correction model: ECM)である。第II部・マクロ・レベルのデータの分析でも、これまでの国内外の研究の流れを重視し、ECM関連のモデルを利用した分析を進める。以下で、具体的な推定モデルを述べる。

2008年にDe Boef & Keele (2008)が、「時間を重視する(``Taking Time seriously”)」と題する論文を公表して以降、1次の自己回帰、移動平均、そして階差(\((p,d,q)=(1,1,1)\))を設定する一般誤差修正モデル(General Error Correction Model: GECM)を、政治学者は多用した。GECMは、各変数の短期変動の効果(short-run effect)と長期均衡からの乖離に対する部分的な調整項(error correction term)からなる。但し、GECMを使うことには、2つの問題があった。

第一に、単位根検定の信頼性の問題がある。GECMの仮説検定とモデルの解釈は、和分(integration)と共和分(cointegration)に依存する。そこで、系列の定常性(stationary)と非定常性(non-stationary)、さらに単位根の有無を評価するために検定を行う。しかし、政治学が扱う世論調査のデータは往々にして時点数が少ない。また一定の値の範囲を、しばしば循環的に行き来する。これを、境界性(bounded)と呼ぶ。データの境界性ゆえに、KPSS検定を使って定常性を、拡張ディッキー=フラー検定(augmented Dicky-Fuller test: ADF検定)検定を使って単位根を検出したとしても、その検定結果が信頼に足るのかという問題が残っていた。仮に単位根の有無が不確かならば、GECMを使う根拠は不十分か、弱まらざるをえない。

第二に、第一の点と関わって、階差の信頼性の問題があった。GECMでは、単位根検定の結果をもとに、短期変動の効果を測定するために整数1次分の階差をとる。しかし、この処理は直観的にも、理論的にも難点がある。例えば、和分\(d\)=0.4 という定常の(頻繁な更新の)系列に対して1次分の階差をとるなら、1-0.4=0.6分の過剰な差分を除いたことになる。一方、\(d\)=1.2という発散する系列に対して1次分の階差しかとらないならば、1-1.2=-0.2分の階差の除去が足りない。さらに、1つの推定モデルには複数の系列が含まれるが、それらの系列の更新の程度が\(d\)=0.4、\(d\)=0.7、\(d\)=1.0、\(d\)=1.2…といったようにばらついているとき、全項に共通して1の階差を取るなら、差分を除去後の系列は不均衡(unbalanced)となる。そして、1次の階差をとるGECMでは、t検定における第I種の過誤が生じると指摘されるようになった。階差、ひいては和分の問題を、政治学の研究者はとりわけ重視した。なぜなら、各種の政治的支持率、マクロ政治・経済指標の和分過程は、ほとんどの場合異なるからである。よってECMを使うのだとしても、GECM(1,1,1)以外のより妥当性の高い推定量の開発、解釈の方法が必要 との見方が主流となった。

そして2015年以降、政治学におけるECMの推定は著しく発展した。2019年と2020年に、Webb, Linn & Lebo (2019, 2020)は、GECMや自己回帰分布ラグモデル(autoregressive distributed lag model: ADL)の長期均衡を正確に解釈する方法を、相次いで提案した。Webb, Linn & Lebo (2019, 2020)は、単位根に関する不確実性が高い場合に、とりわけ長期効果の解釈は困難になるという。少なくとも、右辺変数のラグ項の解釈だけでは不十分となる。そこで、ラグ項を分子とし、左辺変数のラグ項を分母とする長期乗数(Long run Multiplier: LRM)をもとに、長期効果と累積的な将来的効果を判断する代替的な検定方法を示した。LRMの精査は、マクロ政治指標間の分析に応用を見始めている(Wolak & Peterson 2020)。

しかし短期効果も重視される推定の場合、LRMの解釈だけでは、GECMの短期効果をめぐる\(t\)検定の難点を解決しきれない。また本章のように、長期効果・長期的累積効果よりも、各月ごとの経済情報、経済評価の短期効果を知りたい場合、長期効果を測ることに加えて、短期効果の厳密な推定を目指さねばならない。この対処として、2016年にが実数和分に注目し、実数和分をECMに適用しようと呼びかけた特集は、有効な解決方法を示している。実数和分は、既に第4章の分析でも使った。Grant & Lebo (2016)は、実数和分にもとづく差分をとった系列に対して、誤差修正メカニズムを適用する実数和分誤差修正メカニズム(Fractional Error Correction Mechanism: FECM)を使うことを勧めた(参考:Lebo & Grant 2006)。本書でいえば、第4章の実数和分・\(d\)分の差分をとった左辺変数(経済評価)を、短期効果\(\Delta d\)の差分をとった右辺変数(経済状況、経済情報、経済評価など)と部分調整の誤差修正項に回帰する。FECM推定をめぐる3段階のプロセスについては、以下の表にまとめた。

実数和分誤差修正メカニズムの3段階の推定手順

手順 数式 補足
第1段階:部分調整の誤差修正項の算出 \(\mathrm{ECM} = y_{\text{socio}} - \bigl(\beta_0 + \sum_k \beta_k x_k\bigr)\) 従属変数 \(y_{\text{socio}}\) と独立変数 \(x_k\) を用いて誤差修正項 (\(ECM\)) を算出。
第2段階:各系列の実数和分 (\(d\)) をもとにしたフィルター処理 左辺変数 \(y_{\text{socio}}\) を実数和分 \(d\) で処理、部分調整誤差修正項 \(\Delta^{d_{ECM}}ECM\) も同様に処理。 ここで得られるフィルター処理後の系列を第3段階で利用。
第3段階:フィルター処理後の系列をもとにした誤差修正モデル (\(ECM\)) の推定 \(\Delta^{d_{y_{\text{socio}}}}\,y_{\text{socio},t} = \alpha_0 + \alpha_1\,\Delta^{d_{ECM}}ECM_{t-1} + \sum_i \beta_i\,\Delta^{d_{x_{i}}}x_{i,t} + \epsilon_t\) フィルター処理後の系列を用いて、誤差修正項を含む回帰式を推定。

【補足】報道データに関する分析

どのように経済情報スコアを定義したか?

本書では、日本の全国紙3紙の新聞記事のデータを集め、経済情報の変数を作成した。その手順について、以下で説明する。

新聞記事は朝日新聞、日経新聞、読売新聞から「経済」という言葉を含む記事の見出し93万100のデータをもとにしている。集めたデータに対して、\(i\)番目の記事を\(A_i\)、記事\(_i\)に含まれる肯定的な語の数を\(P_i\)、記事\(_i\)に含まれる否定的な語の数を\(N_i\)\(M_i\)を記事\(_i\)の月とすると、以下の手順に基づき、記事を分類する。まず、記事\(_i\)が肯定的であるかを以下式、

\[\begin{eqnarray} D_i^+ = \begin{cases} 1 & \text{if } P_i > 0 \\ 0 & \text{if } P_i = 0 \end{cases} \end{eqnarray}\]

次に、記事\(_i\)が否定的であるかを以下式、

\[\begin{eqnarray} D_i^+ = \begin{cases} 1 & \text{if } N_i > 0 \\ 0 & \text{if } N_i = 0 \end{cases} \end{eqnarray}\]

それぞれによって判別し、次に各月\(m\)について、記事の総数を、

\[\begin{eqnarray} A_m = \sum_{i \text{ where } M_i = m} 1 \end{eqnarray}\]

\(_m\)の肯定的な記事数を、

\[\begin{eqnarray} A_m^+ = \sum_{i \text{ where } M_i = m} D_i^+ \end{eqnarray}\]

\(_m\)の否定的な記事数を、

\[\begin{eqnarray} A_m^+ = \sum_{i \text{ where } M_i = m} D_i^- \end{eqnarray}\]

上記の3式によってそれぞれカウントする。最終的に、月\(_m\)の肯定的情報スコアは、以下の通りである。

\[\begin{eqnarray} S_m^+ = \frac{A_m^+}{A_m} \end{eqnarray}\]

また、否定的情報スコアは、以下の通りである。

\[\begin{eqnarray} S_m^- = \frac{A_m^-}{A_m} \end{eqnarray}\]

上記も参考の上、Rによる前処理の手順は以下の通りである。

#------------------------------
# データの読み込みとテーブル化
#------------------------------
corp_tex1 <- read.csv("newspaper_text_contents.csv", fileEncoding = "SJIS")
tib_corp <- as_tibble(corp_tex1)
tb_corp <- tib_corp %>%
  add_column(id = paste0("news", 1:nrow(tib_corp)), .before = "text")

#------------------------------
# コーパスの作成とトークン分割
#------------------------------
corp <- corpus(tb_corp)
summary(corp)
toks <- tokens(corp)

#------------
# 漢字の処理
#------------
min_count <- 10
kanji_col <- toks %>%
  tokens_select("^[一-龠]+$", valuetype = "regex", padding = TRUE) %>%
  textstat_collocations(min_count = min_count)
toks <- tokens_compound(toks, kanji_col[kanji_col$z > 3, ], concatenator = "")

#----------------
# カタカナの処理
#----------------
kana_col <- toks %>%
  tokens_select("^[ァ-ヶー]+$", valuetype = "regex", padding = TRUE) %>%
  textstat_collocations(min_count = min_count)
toks <- tokens_compound(toks, kana_col[kana_col$z > 3, ], concatenator = "")

#--------------------------------
# 漢字・カタカナおよび数字の処理
#--------------------------------
any_col <- toks %>%
  tokens_select("^[0-9ァ-ヶー一-龠]+$", valuetype = "regex", padding = TRUE) %>%
  textstat_collocations(min_count = min_count)
toks <- tokens_compound(toks, any_col[any_col$z > 3, ], concatenator = "")

#---------------------------------------
# データの整形:DFM作成とフィルタリング
#---------------------------------------
news_df <- toks %>%
  dfm(remove = "") %>%
  dfm_remove("^[ぁ-ん]+$", valuetype = "regex", min_nchar = 2) %>%
  dfm_trim(min_termfreq = 0.50, termfreq_type = "quantile", max_termfreq = 0.99)

#---------------------
# keynessの計算と確認
#---------------------
key <- textstat_keyness(news_df)
head(key, 20) %>% kable()

#--------------------------
# LIWC辞書を用いた感情分析
#--------------------------
dfmt <- dfm(toks)
# ※dictliwcは事前に用意されたLIWC辞書オブジェクトとする
dict_liwc <- dfm_lookup(dfmt, dictliwc)
# 詳細は https://tasukuigarashi.com/lab/archives/1712.html を参照

#------------------------------------------
# 感情データのデータフレーム化と日付の接合
#------------------------------------------
data_liwc <- convert(dict_liwc, to = "data.frame")
data_liwc_em <- data.frame(
  posemo = data_liwc$posemo,
  negemo = data_liwc$negemo,
  sentiment = data_liwc$posemo - data_liwc$negemo
)
data_date <- read.csv("newspaper_text_contents_date.csv")
df_contents <- data.frame(data_liwc_em, data_date)

#--------------------------------------------
# 肯定・否定センチメントの抽出と月ごとの集計
#--------------------------------------------
df_sentiment <- data.frame(
  date = df_contents$date,
  positive = data_liwc$posemo,
  negative = data_liwc$negemo,
  sentiment = df_contents$sentiment
)
colnames(df_sentiment) <- c("date", "positive", "negative", "sentiment")

sentiment_data <- df_sentiment %>%
  group_by(date) %>%
  summarise(
    total_positive = sum(positive),
    mean_positive = sum(positive) / n(),
    total_negative = sum(negative),
    mean_negative = sum(negative) / n(),
    total_sentiment = sum(sentiment),
    mean_sentiment = sum(sentiment) / n()
  )

#------------------------
# CSVファイルへの出力
#------------------------
write.csv(sentiment_data, file = "sentiment.csv", row.names = FALSE)

本文の補足分析と各図表のコード

図3-1:新聞社ごとの肯定的情報スコアと否定的情報スコア

#------------------------
# データの読み込みと整形
#------------------------

dat3_1 <- read_csv("sentiment_data_includingNEWS.csv", locale = locale(encoding = "SJIS")) %>%
  na.omit() %>%
  group_by(newspaper) %>%
  summarise(across(c(positive, negative), mean, na.rm = TRUE)) %>%
  ungroup() %>%
  pivot_longer(cols = c(positive, negative), names_to = "sentiment", values_to = "value") %>%
  mutate(
    sentiment = recode(sentiment, "positive" = "肯定", "negative" = "否定"),
    newspaper = recode(newspaper, "asahi" = "朝日", "nikkei" = "日経", "yomiuri" = "読売"),
    newspaper = factor(newspaper, levels = c("朝日", "日経", "読売")),
    sentiment = factor(sentiment, levels = c("肯定", "否定"))
  )

#-----------
# ANOVA検定
#-----------
anova_result <- dat3_1 %>% aov(value ~ newspaper * sentiment, data = .)
summary(anova_result)

#----------------
# Tukey HSD 検定
#----------------
tukey_result <- TukeyHSD(anova_result)
print(tukey_result)


#----------------
# プロットの作成
#----------------
windows(10, 8)
dodge <- position_dodge(width = 0.8)

ggplot(dat3_1, aes(x = newspaper, y = value, fill = sentiment, group = sentiment)) +
    geom_bar(stat = "identity", position = dodge, width = 0.7) +  
    geom_label(aes(label = round(value, 2)),
             position = dodge, vjust = -0.2, size = 3, fill = "white", color = "black", label.size = 0.25) +
  xlab("新聞社") +
  ylab("肯定的/否定的情報スコア") +
  geom_signif(comparisons = list(c("朝日", "日経"), c("日経", "読売"), c("朝日", "読売")),
              map_signif_level = TRUE, y_position = c(0.34, 0.34, 0.36),
              annotation = c("***.", "***", "*"), tip_length = 0) +
  geom_signif(
    y_position = c(0.25, 0.28, 0.32),
    xmin = c(0.8, 1.8, 2.8),
    xmax = c(1.2, 2.2, 3.2),
    annotation = c("NS.", "***", "***"),
    tip_length = 0
  ) +
  theme_bw() +
  scale_fill_grey() +
  labs(fill = "情報")

表3-2: 新聞社ごとの記事の見出し数

#------------------------------------
# データの読み込みと度数分布表の作成
#------------------------------------
dat3_2 <- read.csv("newspaper_text.csv", fileEncoding = "SJIS") %>% 
  { table(.$newspaper) } %>%           
  as.data.frame() %>%                  
  { cbind(c("朝日", "日経", "読売"), .) } %>% 
  t()                                   

表3-3: 経済情報スコアに関する記述統計と実数和分分析の結果

#------------------
# データの読み込み
#------------------
dat3_3 <- read.csv("approve_economy.csv", fileEncoding = "SJIS")
attach(dat3_3)

#-------------------------
# 経済情報スコアの記述統計
#-------------------------
des_ts <- describe(data.frame(positive, negative))

des_stats <- des_ts[, c("n", "mean", "sd", "median", "min", "max")]
colnames(des_stats) <- c("n", "平均", "標準偏差", "中央値", "最小値", "最大値")

#-------------------------
# 経済情報スコアのFI分析
#-------------------------
#肯定
fdGPH(na.omit(positive))

#否定
fdGPH(na.omit(negative))

図3-2:経済報道、政治経済的出来事、景気循環の関係

#------------------
# データの読み込み
#------------------
dat3_2_1 <- read.csv("approve_economy.csv", fileEncoding = "SJIS") %>%
  dplyr::select(yearmon, positive, negative) %>%
  stats::setNames(c("yearmon", "肯定", "否定")) %>%
  tidyr::gather("経済報道", "value", -yearmon)

#-------------------------------
# A: 経済報道と政治経済的出来事
#-------------------------------
c1 <- dat3_2_1 %>%
  ggplot2::ggplot(aes(x = as.Date(yearmon, "%Y-%m-%d"), y = value)) +
  geom_line(aes(linetype = 経済報道)) +
  theme_minimal() +
  xlab("年") +
  ylab("肯定的/否定的経済報道") +
  # 重要イベントの縦線 & 注釈
  annotate("text", x = as.Date("1976-02-01", "%Y-%m-%d"),
           y = 2, label = "第1次石油ショック(1973)", angle = 45, size = 2) +
  geom_vline(xintercept = as.Date("1973-10-01")) +
  annotate("text", x = as.Date("1989-01-01", "%Y-%m-%d"),
           y = 2, label = "消費税導入(1989)", angle = 45, size = 2) +
  geom_vline(xintercept = as.Date("1989-04-01")) +
  annotate("text", x = as.Date("1991-01-01", "%Y-%m-%d"),
           y = 2, label = "バブル経済崩壊(1990)", angle = 45, size = 2) +
  geom_vline(xintercept = as.Date("1990-01-01")) +
  annotate("text", x = as.Date("1997-09-01", "%Y-%m-%d"),
           y = 2, label = "アジア通貨危機(1997)", angle = 45, size = 2) +
  geom_vline(xintercept = as.Date("1997-07-01")) +
  annotate("text", x = as.Date("2008-11-01", "%Y-%m-%d"),
           y = 2, label = "グローバル経済危機(2008)", angle = 45, size = 2) +
  geom_vline(xintercept = as.Date("2008-09-01")) +
  annotate("text", x = as.Date("2011-03-01", "%Y-%m-%d"),
           y = 2, label = "東日本大震災(2011)", angle = 45, size = 2) +
  geom_vline(xintercept = as.Date("2011-03-01")) +
  annotate("text", x = as.Date("2013-03-01", "%Y-%m-%d"),
           y = 2, label = "アベノミクス導入(2012)", angle = 45, size = 2) +
  geom_vline(xintercept = as.Date("2012-12-01")) +
  annotate("text", x = as.Date("2020-04-01", "%Y-%m-%d"), 
           y = c(45), label = c("緊急事態宣言(2020)"), angle=315,size=5)+
  geom_vline(xintercept = as.Date("2020-04-01"))+
  ggtitle("A:経済報道と政治経済的出来事")


#------------------------
# B: 経済報道と景気循環
#------------------------
dat3_2_2 <- read.csv("approve_economy.csv", fileEncoding = "SJIS") %>%
  dplyr::select(yearmon, positive, negative) %>%
  stats::setNames(c("yearmon", "肯定", "否定")) %>%
  tidyr::gather("news", "value", -yearmon)

c2 <- dat3_2_2 %>%
  ggplot2::ggplot(aes(x = as.Date(yearmon, "%Y-%m-%d"), y = value)) +
  geom_line(aes(linetype = news), size = 1) +
  theme_minimal() +
  xlab("年") +
  ylab("肯定的/否定的経済報道") +
  ggtitle("B:経済報道と景気循環") +
  geom_segment(aes(x=as.Date("1963-12-01"),
                   xend=as.Date("1964-10-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1965-10-01"),
                   xend=as.Date("1970-07-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1971-12-01"),
                   xend=as.Date("1973-11-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1975-03-01"),
                   xend=as.Date("1977-01-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1977-10-01"),
                   xend=as.Date("1980-02-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1983-02-01"),
                   xend=as.Date("1985-06-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1986-11-01"),
                   xend=as.Date("1991-02-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1993-10-01"),
                   xend=as.Date("1997-05-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("1999-12-01"),
                   xend=as.Date("2000-11-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("2002-01-01"),
                   xend=as.Date("2008-02-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("2009-03-01"),
                   xend=as.Date("2012-03-01"),y=0.035,yend=0.035,size=1.5))+
  geom_segment(aes(x=as.Date("2012-11-01"),
                   xend=as.Date("2020-05-01"),y=0.035,yend=0.035,size=1.5))+
  theme(legend.position = "none")


#----------------
# プロットの作成
#----------------
windows(30, 20)
gridExtra::grid.arrange(c1, c2, nrow = 2)

図3-3: 党派性、経済情報から経済評価への作用に関する実数和分分析の結果

FECM推定は、Stataによって行っている。以下のスクリプトは、Stataで推定を行うためのものである。コードの例は、社会志向の肯定的評価を従属変数とする場合のみであるが、他の場合についても変数を変更することで分析可能である。

*************************************************************
* 経済評価についての実数和分誤差修正メカニズムの分析(FECM)*
*************************************************************

/*
必要に応じて、以下を実行
 clear
 cd "C:Users\yourpath"
 use " ", clear
 */

***---time series setting
tsset time_id

***----variables setting
drop rcpi_socgd-_est_reg39 
*clear後であれば不要

gen sociotropic_gd=q5c1+q5c2
gen sociotropic_bd=q5c4+q5c5

gen liv_gd=q3c1+q3c2
gen liv_bd=q3c4+q3c5

gen ln_nav = log(nav_high)
gen lnIIP = log(iip)


*************************
* 社会志向の肯定的評価  *
*************************

***---1st step: 残差の予測値の計算----*


reg sociotropic_gd cpi
predict rcpi_socgd, resid

reg sociotropic_gd unemp
predict runemp_socgd, resid

reg sociotropic_gd ln_nav
predict rnav_socgd, resid

reg sociotropic_gd ruling
predict rldp_socgd, resid

reg sociotropic_gd m2
predict rm2_socgd, resid

reg sociotropic_gd iip
predict riip_socgd, resid

reg sociotropic_gd interest
predict rint_socgd, resid

reg sociotropic_gd positive
predict rpositive_socgd, resid

reg sociotropic_gd negative
predict rnegative_socgd, resid


reg sociotropic_gd ruling positive negative  cpi unemp ln_nav lnIIP   business_cycle crisis_dum 
predict rsocgd_full, resid

reg sociotropic_gd  positive negative  cpi unemp ln_nav lnIIP  business_cycle crisis_dum 
predict rsocgd_no, resid


***---2nd step: d値によるフィルタリンリングの実施 ----*

arfima sociotropic_gd,  iterate(2000)
predict d_socgd, fdifference

arfima liv_gd, iterate(2000)
predict d_livgd, fdifference

arfima cpi, iterate(2000)
predict d_cpi, fdifference

arfima unemp, iterate(2000)
predict d_unemp, fdifference

arfima ln_nav, iterate(2000)
predict d_nav, fdifference

arfima ruling, iterate(2000)
predict d_rul, fdifference

arfima iip, iterate(2000)
predict d_iip, fdifference


arfima interest, iterate(2000)
predict d_int, fdifference

arfima positive, iterate(2000)
predict d_positive, fdifference

arfima negative, iterate(2000)
predict d_negative, fdifference

arfima indep, iterate(2000)
predict d_indep, fdifference


arfima rsocgd_full, iterate(2000)
predict d_rsocgd_full, fdifference


arfima rsocgd_no, iterate(2000)
predict d_rsocgd_no, fdifference


***---3rd step: OLSによるFECM推定----*

* 各種のパラメターの設定
 scalar ecmsig =-1.645 
 scalar ecmMCV =-3.867 
 scalar up = 1.96 
 scalar lp =-1.96 
 scalar alpha = .05

*******党派性無モデル********

*----AICの比較から選択される特定化
reg d_socgd  d_positive d_negative l.rpositive_socgd
*Akaike information criteria
estat ic
*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        656 -1511.357  -1476.208       4    2960.417   2978.361
-----------------------------------------------------------------------------
*\

*Ramsey-reset test
estat ovtest
*Breeusch-Pagen Cook-Weisberg test for heteroskedasticity
estat hettest
*結果の保存
outreg2 using myreg.doc, replace ctitle(Model 1) 
est sto reg1

* Breusch Godfrey test 
estat bgodfrey, lags(1) 
matrix p1 = r(p) 
scalar rej1 = (p1[1,1]<alpha) 
estat dwatson 
scalar ddw = r(dw)

*----AICの比較から選択されない特定化
reg d_socgd  d_positive d_negative l.rnegative_socgd
*Akaike information criteria
estat ic

*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        656 -1511.357  -1482.033       4    2972.067   2990.012
-----------------------------------------------------------------------------
              
*\




*******フルモデル*******            

reg d_socgd  d_positive d_negative  d_cpi d_unemp d_nav d_iip  business_cycle crisis_dum l.rcpi_socgd
estat ic


*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        650 -1499.521  -1417.756      10    2855.512   2900.282
-----------------------------------------------------------------------------
*\


reg d_socgd  d_positive d_negative  d_cpi d_unemp d_nav d_iip  business_cycle crisis_dum l.runemp_socgd
estat ic


*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        650 -1499.521  -1415.833      10    2851.666   2896.436
-----------------------------------------------------------------------------
*\


reg d_socgd  d_positive d_negative  d_cpi d_unemp d_nav d_iip  business_cycle crisis_dum l.rnav_socgd
estat ic


*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        650 -1499.521  -1418.276      10    2856.552   2901.322
-----------------------------------------------------------------------------
*\


reg d_socgd  d_positive d_negative  d_cpi d_unemp d_nav d_iip  business_cycle crisis_dum l.riip_socgd
estat ic


*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        650 -1499.521  -1417.508      10    2855.017   2899.787
-----------------------------------------------------------------------------
*\


reg d_socgd  d_positive d_negative  d_cpi d_unemp d_nav d_iip  business_cycle crisis_dum l.rldp_socgd
estat ic


*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        650 -1499.521  -1415.999      10    2851.998   2896.767
-----------------------------------------------------------------------------
*\


*----AICの比較から選択される特定化
reg d_socgd  d_positive d_negative  d_cpi d_unemp d_nav d_iip  business_cycle crisis_dum l.rpositive_socgd
estat ic

*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        649 -1497.569  -1415.066      10    2850.133   2894.887
-----------------------------------------------------------------------------
*\

*Ramsey-reset test
estat ovtest*Ramsey-reset test
estat ovtest
*Breeusch-Pagen Cook-Weisberg test for heteroskedasticity
estat hettest
*結果の保存
outreg2 using myreg.doc, append ctitle(Model 2)
outreg2 using replication_sa.doc, replace ctitle(Poisitive)
est sto reg2

reg d_socgd  d_positive d_negative  d_cpi d_unemp d_nav d_iip  business_cycle crisis_dum l.rnegative_socgd
estat ic

*\
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |        Obs  ll(null)  ll(model)      df         AIC        BIC
-------------+---------------------------------------------------------------
           . |        649 -1497.569  -1416.665      10    2853.331   2898.085
-----------------------------------------------------------------------------
*\

上記の推定結果をもとにした係数プロットのRコードは、次のとおりである。

#------------------
# データの読み込み
#------------------
dat3_3<-read.csv("fecm_economy_result.csv", fileEncoding = "SJIS")


#----------------
# プロットの作成
#----------------
pd <-position_dodge(0.4)
df_full$モデル = factor(df_full$モデル, levels=c('フルモデル', '党派性無'))

pd <-position_dodge(0.4)
df_full$従属変数 = factor(df_full$従属変数, levels=c('社会志向(+)','社会志向(-)', '個人志向(+)',
                                             '個人志向(-)'))


pd <-position_dodge(0.4)
df_full$独立変数 = factor(df_full$独立変数, levels=c('否定情報', '肯定情報', '無党派割合', '野党支持率', '与党支持率'))

windows(40, 35)
ggplot(df_full, aes(x=独立変数, y=as.numeric(coef), color = モデル), na.rm=T) + 
  geom_errorbar(aes(ymin=as.numeric(lower), ymax=as.numeric(upper)), size=1, position=pd, width=.1, na.rm=T) +
  geom_line(position=pd, na.rm=T) +
  geom_point(position=pd, size=3, shape=21, fill="white") + 
  scale_colour_grey(name="モデル") +
  facet_wrap(~ 従属変数, ncol=2) +
  coord_flip() +
  geom_hline(yintercept = 0) +
  ylab("係数") + theme_bw() +
  geom_text(data = df_full[df_full$モデル == 'フルモデル', ], 
            aes(label = paste0(round(as.numeric(coef), 2), "\n[", round(as.numeric(lower), 2), ", ", round(as.numeric(upper), 2), "]")), 
            position = pd, vjust = 1.5, hjust = 0.5, size = 3) + 
  ggtitle("")

第4章 政治的支持はどのように動いてきたのか?

本文の補足分析と各図表のコード

図4-1:与党支持率、野党支持率、無党派層の割合の推移

図4-2:内閣支持率、内閣不支持率の推移

#----------------
# 関数の読み込み
#----------------
source("plot4_1.R")
source("plot4_2.R")
source("plot4_1anno.R")
source("plot4_2anno.R")


#------------------
# データの読み込み
#------------------
dat4_1<-read.csv("approve_economy.csv",fileEncoding = "SJIS")
attach(dat4_1)



#----------------------------
# 政党支持率のプロットの作成
#----------------------------
d1 <- plot4_1(ruling, "与党支持率", "与党支持率の推移と政治経済的出来事")
d2 <- plot4_1(dat4_1$opposite, "野党支持率", "野党支持率の推移と政治経済的出来事")
d3 <- plot4_1(indep, "無党派層割合", "無党派層割合の推移と政治経済的出来事")

windows(80, 50)
grid.arrange(d1, d2, d3, ncol = 1)


#--------------------------------------
# 内閣支持率・不支持率のプロットの作成
#--------------------------------------
d4 <- plot4_2(approve, "内閣支持率", "内閣支持率の推移と政治経済的出来事")
d5 <- plot4_2(disapprove, "内閣不支持率", "内閣不支持率の推移と政治経済的出来事")

windows(80, 60)
grid.arrange(d4, d5, ncol = 1)

表4-1:与党支持率、野党支持率、無党派層割合の実数和分分析の結果

#---------------------- 
# FIの計算:与党支持率
#---------------------- 
fdGPH(na.omit(ruling))

#---------------------- 
# FIの計算:野党支持率
#---------------------- 
fdGPH(na.omit(opposite))

#---------------------- 
# FIの計算:無党派割合
#---------------------- 
fdGPH(na.omit(indep))

表4-2:内閣支持率・不支持率の実数和分分析の結果

#---------------------- 
# FIの計算:内閣支持率
#---------------------- 
fdGPH(na.omit(approve))

#------------------------ 
# FIの計算:内閣不支持率
#------------------------ 
fdGPH(na.omit(disapprove))

図4-4: 与党派・野党派間の内閣支持率/不支持率、内閣支持率/不支持率の党派性差異

#------------------------
# 関数の読み込み
#------------------------
source("plot4_4df.R")
source("plot4_4_1.R")
source("plot4_4_2.R")

#------------------------
# データの読み込みと整形
#------------------------
dat4_4 <- read_csv("approve_economy.csv", locale = locale(encoding = "SJIS"))


#------------------- 
# 政権交代期の設定
#-------------------
admin <- data.frame(
  start = as.Date(c('1993-08-01', '2009-09-01')), 
  end   = as.Date(c('1993-05-01', '2012-11-01'))
)

#----------------------------
# データ作成とプロットの作成
#----------------------------
# 党派別の内閣支持率・不支持率の2系列の描画
tb_long_ap <- dat4_4 %>% with(plot4_4df(yearmon, ap_ldp, ap_opposite, "党派別の内閣支持率"))
d1 <- plot4_4_1(tb_long_ap, "与党派・野党派間の内閣支持率", "割合", "党派別の内閣支持率")

tb_long_dis <- dat4_4 %>% with(plot4_4df(yearmon, dis_ldp, dis_opposite, "党派別の内閣不支持率"))
d2 <- plot4_4_1(tb_long_dis, "与党派・野党派間の内閣不支持率", "割合", "党派別の内閣不支持率")

# 党派性差異の1系列の描画(支持率)
df_ap_diff <- dat4_4 %>% transmute(yearmon, 党派性差異 = abs(ap_ldp - ap_opposite))
d3 <- plot4_4_2(df_ap_diff, "内閣支持率の党派性差異", "党派性差異")

# 党派性差異の1系列の描画(不支持率)
df_dis_diff <- dat4_4 %>% transmute(yearmon, 党派性差異 = abs(dis_ldp - dis_opposite))
d4 <- plot4_4_2(df_dis_diff, "内閣不支持率の党派性差異", "党派性差異")

#---------------
# プロットの表示
#---------------
windows(70, 50)
grid.arrange(d1, d2, d3, d4, ncol = 1)

第5章 政治的支持は何によって動いてきたのか?

本文の補足分析と各図表のコード

FECM推定は、Stataによって行っている。以下のスクリプトは、Stataで推定を行うためのものである。コードの例は、社会志向の肯定的評価を従属変数とする場合のみであるが、他の場合についても変数を変更することで分析可能である。詳細なコードについては、筆者へのコンタクトにより入手可能である。

図5-1:経済情報,経済評価から政党支持率への作用に関する実数和分誤差修正メカニズムによる分析

図5-2:経済情報,経済評価から政党支持率への作用に関する時期ごとの分析(実数和分誤差修正メカニズム)

以下では、与党支持率に関する手順のみを示しているが、野党支持率、無党派割合についても、変数名を置き換え、同様の手順により推定を行った。

**************************
*  結果変数:与党支持率  *
**************************

***---1st step: 残差の予測値の計算
reg ruling sociotropic_gd
predict rsociogd_rul, resid

reg ruling liv_gd
predict rlivgd_rul, resid

reg ruling sociotropic_bd
predict rsociobd_rul, resid

reg ruling liv_bd
predict rlivbd_rul, resid

reg ruling cpi
predict rcpi_rul, resid

reg ruling unemp
predict runemp_rul, resid

reg ruling ln_nav
predict rnav_rul, resid

reg ruling ruling
predict rldp_rul, resid

reg ruling coincidentdi
predict rdi_rul, resid


reg ruling iip
predict riip_rul, resid

reg ruling interest
predict rint_rul, resid

reg ruling positive
predict rpositive_rul, resid

reg ruling negative
predict rnegative_rul, resid

reg ruling sociotropic_gd liv_gd positive negative  cpi unemp lnNikkei lnIIP  business_cycle crisis_dum corruption abuse admin_event  
predict rrul_gd, resid


reg ruling sociotropic_bd liv_bd positive negative  cpi unemp lnNikkei lnIIP  business_cycle crisis_dum corruption abuse admin_event  
predict rrul_bd, resid


***---2nd step: d値によるフィルタリングの実施
arfima d.rrul_gd, iterate(2000)
predict d_rrul_gd, fdifference


arfima d.rrul_bd, iterate(2000)
predict d_rrul_bd, fdifference



***---3rd step: OLSによるFECM推定
********
*図5-1*
********
*肯定的評価に関する採用されたモデル(選別の手順については図3-3コードを参照)
reg d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_gd

*Akaike information criteria
estat ic
*Ramsey-reset test
estat ovtest
*Breeusch-Pagen Cook-Weisberg test for heteroskedasticity
estat hettest
*結果の保存
outreg2 using myreg.doc, replace ctitle(Model 1) 
est sto reg1

* Breusch Godfrey test 
estat bgodfrey, lags(1) 
matrix p1 = r(p) 
scalar rej1 = (p1[1,1]<alpha) 
estat dwatson 
scalar ddw = r(dw)

*否定的評価に関する採用されたモデル(同様に手順は図3-3を参照)
reg d_rul d_socbd d_livbd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_bd
***検定など省略


********
*図5-2*
********
*肯定的評価  
*1960-1980
reg d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_gd if time_id >0 & time_id < 194
***検定など省略


*1980-2000
reg d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_gd if time_id >193 & time_id < 435
***検定など省略

*2000-
reg d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_gd if time_id >434
***検定など省略


*否定的評価
*1960-1980
reg d_rul d_socbd d_livbd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_bd if time_id >0 & time_id < 194
***検定など省略

*1980-2000
reg d_rul d_socbd d_livbd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_bd if time_id >193 & time_id < 435
***検定など省略

*2000-
reg d_rul d_socbd d_livbd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rrul_bd if time_id >434
***検定など省略

図5-3:党派性,経済情報,経済評価から内閣支持率・不支持率への作用に関する実数和分誤差修正メカニズムによる分析

図5-4:党派性,経済情報,経済評価から内閣支持率・不支持率への作用に関する時期ごとの分析(実数和分誤差修正メカニズム)

****************
*  内閣支持率 *
****************

***---1st step: 残差の予測値の計算
reg approve sociotropic_gd
predict rsociogd_ap, resid

reg approve liv_gd
predict rlivgd_ap, resid

reg approve cpi
predict rcpi_ap, resid

reg approve unemp
predict runemp_ap, resid

gen ln_nav=log(nav_high)
reg approve ln_nav
predict rnav_ap, resid

reg approve ruling
predict rldp_ap, resid

reg approve coincidentdi
predict rdi_ap, resid

reg approve m2
predict rm2_ap, resid

reg approve iip
predict riip_ap, resid

reg approve interest
predict rint_ap, resid

reg approve positive
predict rpositive, resid

reg approve negative
predict rnegative, resid

reg approve ruling sociotropic_gd liv_gd positive negative  cpi unemp lnNikkei lnIIP  business_cycle crisis_dum corruption abuse admin_event  
predict rfull, resid


reg approve sociotropic_gd liv_gd positive negative  cpi unemp lnNikkei lnIIP  business_cycle crisis_dum corruption abuse admin_event  
predict rsocfull, resid


***---2nd step: d値によるフィルタリングの実施

arfima d.approve, iterate(2000)
predict d_ap, fdifference

arfima d.sociotropic_gd,  iterate(2000)
predict d_socgd, fdifference

arfima d.liv_gd, iterate(2000)
predict d_livgd, fdifference

arfima d.cpi, iterate(2000)
predict d_cpi, fdifference

arfima d.unemp, iterate(2000)
predict d_unemp, fdifference

arfima d.lnNikkei, iterate(2000)
predict d_nikkei, fdifference

arfima d.ruling, iterate(2000)
predict d_rul, fdifference

arfima d.lnIIP, iterate(2000)
predict d_iip, fdifference


arfima d.interest, iterate(2000)
predict d_int, fdifference

arfima positive, iterate(2000)
predict d_positive, fdifference

arfima negative, iterate(2000)
predict d_negative, fdifference

arfima d.indep, iterate(2000)
predict d_indep, fdifference

arfima rfull, iterate(2000)
predict d_rfull, fdifference

arfima rsocfull, iterate(2000)
predict d_rsocfull, fdifference

arfima rcsifull, iterate(2000)
predict d_rcsifull, fdifference


***---3rd step: OLSによるFECM推定
********
*図5-3*
********  
reg d_ap d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nikkei d_iip  business_cycle crisis_dum corruption abuse admin_event  l.d_rfull
***検定など省略

********
*図5-4*
********
*1960-1980
reg d_ap d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nav  business_cycle crisis_dum corruption abuse admin_event  l.d_rfull if time_id > 0 & time_id < 194
***検定など省略

*1980-2000
reg d_ap d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nav  business_cycle crisis_dum corruption abuse admin_event  l.d_rfull if time_id > 193 & time_id < 435
***検定など省略

*2000-
reg d_ap d_rul d_socgd d_livgd d_positive d_negative  d_cpi d_unemp d_nav  business_cycle crisis_dum corruption abuse admin_event  l.d_rfull if time_id > 434 
est sto reg40
***検定など省略


*与党支持率なしモデルでは、上記から与党支持率を除いた特定化のもとに推定を行っている。内閣不支持率を結果変数とする各種モデルの手順は省略しているが、同様の手順により推定を行っている。

第6章:所得は経済評価、投票選択を決めるのか?―観察データの分析(1)

【補足】推定方法の説明

党派性差異をどのように計算するか?

経済評価の上昇程度の差

以下では、第6章で行う党派性差異の推定方法について説明する(図6-7から図6-9を対象)。はじめに社会志向の経済評価に関しては、以下の特定化のもとに、最小二乗法推定(ordinary least square estimation: OLS)を行う;

\[\begin{eqnarray} \nonumber y_{socio}&=&\beta_0+\beta_1x_{income}+\beta_2x_{partisan}+\beta_3x_{ego}+\beta_4x_{sex}+\beta_5x_{age}+\beta_6x_{education}\\ &+&\beta_7x_{employment}+\beta_8x_{interest}+\epsilon. \end{eqnarray}\tag{1}\]

但し、\(y_{socio}\)は社会志向の経済評価、\(\beta_k\)\(k\)番目の変数の係数を指し、各変数は党派性ダミー\(\left(x_{partisan}\right)\)、所得階層\(\left(x_{income}\right)\)、個人志向の経済評価\(\left(x_{ego}\right)\)、性別\(\left(x_{sex}\right)\)、年齢\(\left(x_{age}\right)\)、教育程度\(\left(x_{education}\right)\)、就業状況\(\left(x_{employment}\right)\)、政治関心\(\left(x_{interest}\right)\)\(k=8\)とサンプル・サイズ\(n\)のもとで\(n\times k\)からなる変数行列をなし、\(\epsilon\)は誤差項をである 。(1)式は社会志向の経済評価に関するモデルであるが、個人志向の経済評価に関するモデルでは、左辺が\(y_{ego}\)となり、右辺の\(\beta_3x_{ego}\)\(\beta_3x_{socio}\)となる。 (1)式のモデルの推定結果をもとに、他の要素を一定にそろえた上で、党派性と所得階層を変化させ経済評価の上昇の程度を測るシミュレーションを行う 。各党派性ダミーが1の時の社会志向の経済評価\(y_{\mathrm{socio}}^{partisan=1}\)と、\

\[\begin{eqnarray} \widehat{y_{\mathrm{socio}}^{\mathrm{partisan}=1}} &=& \beta_0 + \beta_1 x_{\mathrm{income}} + \beta_2 \cdot 1 + \beta_3 x_{\mathrm{ego}} + \beta_4 x_{\mathrm{sex}} + \beta_5 x_{\mathrm{age}} + \beta_6 x_{\mathrm{education}} \\ &+& \beta_7 x_{\mathrm{employment}} + \beta_8 x_{\mathrm{interest}} \end{eqnarray} \tag{2}\]

各党派性ダミーが0の時の社会志向の経済評価\(y_{\mathrm{socio}}^{partisan=0}\)

\[\begin{eqnarray} \widehat{y_{\mathrm{socio}}^{\mathrm{partisan}=0}} &=& \beta_0 + \beta_1 x_{\mathrm{income}} + \beta_2 \cdot 0 + \beta_3 x_{\mathrm{ego}} + \beta_4 x_{\mathrm{sex}} + \beta_5 x_{\mathrm{age}} + \beta_6 x_{\mathrm{education}} \\ &+& \beta_7 x_{\mathrm{employment}} + \beta_8 x_{\mathrm{interest}} \end{eqnarray} \tag{3}\]

以上、(2)式と(3)式の差、

\[\begin{eqnarray} \Delta\widehat{y_{\mathrm{socio}}^{partisan}}=\widehat{y_{\mathrm{socio}}^{partisan=1}}-\widehat{y_{\mathrm{socio}}^{partisan=0}} \end{eqnarray}\tag{4}\]

上記(4)式を、社会志向の経済評価をめぐる党派性間での上昇の程度の差(\(PFD_{socio}^{partisan}\))と定める。この上昇の程度の差を、経済評価の上昇の程度をめぐる党派性差異として使う。

投票確率の差

次に投票確率は、以下の特定化のロジスティック回帰モデルをもとに計算する;

\[\begin{eqnarray} \nonumber ln\left(\frac{y_{incumbent}}{1-y_{incumbent}}\right)&=&\beta_0+\beta_1x_{income}+\beta_2x_{partisan}+\beta_3x_{socio}+\beta_4x_{ego}+\beta_5x_{sex}+\beta_6x_{age}\\ &+&\beta_7x_{education}+\beta_8x_{employment}+\beta_{9}x_{interest}. \end{eqnarray}\tag{5}\]

ここで、\(y_{incumbent}\)は、現職すなわち与党の候補者への(5)式は対数オッズにもとづく表記であるが、これを確率に変換すると以下(6)式のとおりである;

\[\begin{eqnarray} p=\frac{e^{ln{\left(\frac{y_{incumbent}}{1-y_{\mathrm{incumbent}}}\right)}}}{1+e^{ln{\left(\frac{y_{incumbent}}{1-y_{\mathrm{incumbent}}}\right)}}} \end{eqnarray}\tag{6}\]

(6)式をベースに、党派性ダミーが1の時と0の時の確率差を以下のように計算する;

\[\begin{eqnarray} \mathrm{\Delta p}=p\left(x_{\mathrm{partisan}}=1\right)-p\left(x_{\mathrm{partisan}}=0\right) \end{eqnarray}\tag{7}\]

(7)式の\(\Delta p\)を、現職投票をめぐる党派性間での投票確率差(\(PFD_{incumbent}^{partisan}\))と定める。この投票確率差を、投票確率をめぐる党派性差異として使う。

本文の補足分析と各図表のコード

図6-2:所得階層と経済評価

#----------------
# 関数の読み込み
#----------------
source("plot6_2df.R")
source("plot6_2.R")


#------------------
# データの読み込み
#------------------
# 各データは利用申請が必要です。利用申請後にデータを入手し、
# データの作成方法などの詳細は筆者にお問い合わせください。

file_names <- c("JES_whole.csv", "dfjes2.csv", "dfjes3.csv", "dfjes4.csv", "dfjes5.csv", "dfjes6.csv")
data_labels <- c("whole", "jes2", "jes3", "jes4", "jes5", "jes6")

data_list <- setNames(lapply(file_names, read.csv), data_labels)

df_34 <- rbind(data_list$jes3, data_list$jes4)
df_56 <- rbind(data_list$jes5, data_list$jes6)

dat6_2 <- list(
  whole = data_list$whole,
  jes2  = data_list$jes2,
  jes34 = df_34,
  jes56 = df_56
)



#-------------
# データの成形
#-------------
dat6_2 <- lapply(dat6_2, function(df) {
  list(
    socio = plot6_2df(df, "socio"),
    ego   = plot6_2df(df, "ego")
  )
})

#----------------------
# プロットの作成と表示
#----------------------
plot_titles <- list(
  whole = list(socio = "全体: 社会志向", ego = "全体: 個人志向"),
  jes2  = list(socio = "JES2(99年以前)",  ego = "JES2(99年以前)"),
  jes34 = list(socio = "JES3-4(2000年代)", ego = "JES3-4(2000年代)"),
  jes56 = list(socio = "JES5-6(2010年代)", ego = "JES5-6(2010年代)")
)

plot_list <- list()
for (key in names(dat6_2)) {
  proc <- dat6_2[[key]]
  plot_list[[paste0(key, "_socio")]] <- plot6_2(proc$socio, "socio", plot_titles[[key]]$socio)
  plot_list[[paste0(key, "_ego")]]   <- plot6_2(proc$ego, "ego",   plot_titles[[key]]$ego)
}

windows(50, 40)
grid.arrange(
  plot_list$whole_socio, plot_list$jes2_socio, plot_list$jes34_socio, plot_list$jes56_socio,
  plot_list$whole_ego,   plot_list$jes2_ego,   plot_list$jes34_ego,   plot_list$jes56_ego,
  ncol = 4
)

【補足】Tukey-HSD検定の結果

図6-2に関するTukey-HSDの結果は、それぞれ以下の通りである。

  • 全体の社会志向の経済評価に関する結果
#----------------
# 関数の読み込み
#----------------
source("plot6_2tukey.R")


#---------------------------------
results_all_socio_tukey <- plot6_2tukey(df_jes2_processed_socio, "socio", "group_income")

res_table <- results_all_socio_tukey$tukey_result$`df[[group_var]]`

tb_tukey <- kbl(res_table, 
    format = "html",  
    digits = 3) %>%
  kable_styling(full_width = FALSE)

全体の社会志向の経済評価に関するTukey-HSDの結果

diff lwr upr p adj
所得(中)-所得(高) 0.070 0.004 0.135 0.033
所得(低)-所得(高) 0.063 -0.005 0.131 0.078
所得(低)-所得(中) -0.007 -0.086 0.072 0.978
  • JES2の社会志向の経済評価に関するTukey-HSDの結果
diff lwr upr p adj
所得(中)-所得(高) 0.070 0.004 0.135 0.033
所得(低)-所得(高) 0.063 -0.005 0.131 0.078
所得(低)-所得(中) -0.007 -0.086 0.072 0.978
  • JES3-4の社会志向の経済評価に関する分析結果
diff lwr upr p adj
所得(中)-所得(高) -0.034 -0.110 0.042 0.550
所得(低)-所得(高) -0.043 -0.115 0.029 0.335
所得(低)-所得(中) -0.010 -0.067 0.048 0.918
  • JES5-6の社会志向の経済評価に関する分析結果
diff lwr upr p adj
所得(中)-所得(高) -0.062 -0.102 -0.022 0.001
所得(低)-所得(高) -0.139 -0.179 -0.100 0.000
所得(低)-所得(中) -0.077 -0.117 -0.037 0.000
  • 全体の個人志向の経済評価に関する分析結果
diff lwr upr p adj
所得(中)-所得(高) -0.246 -0.272 -0.220 0
所得(低)-所得(高) -0.425 -0.450 -0.400 0
所得(低)-所得(中) -0.179 -0.205 -0.153 0
  • JES2の個人志向の経済評価に関する分析結果
diff lwr upr p adj
所得(中)-所得(高) 0.046 -0.006 0.099 0.097
所得(低)-所得(高) 0.006 -0.051 0.063 0.969
所得(低)-所得(中) -0.041 -0.107 0.026 0.321
  • JES3-4の個人志向の経済評価に関する分析結果
diff lwr upr p adj
所得(中)-所得(高) 0.046 -0.006 0.099 0.097
所得(低)-所得(高) 0.006 -0.051 0.063 0.969
所得(低)-所得(中) -0.041 -0.107 0.026 0.321
  • JES5-6の個人志向の経済評価に関する分析結果
diff lwr upr p adj
所得(中)-所得(高) 0.046 -0.006 0.099 0.097
所得(低)-所得(高) 0.006 -0.051 0.063 0.969
所得(低)-所得(中) -0.041 -0.107 0.026 0.321

図6-3:所得階層と投票割合

#---------------------------------------------
# 関数の読み込み(図6-2作成時と同じ関数を利用)
#---------------------------------------------
source("plot6_2df.R")
source("plot6_2.R")

#-------------
# データの成形
#-------------
dat6_3 <- list(
  all   = df,
  jes2  = dfjes2,
  jes34 = df_jes34,
  jes56 = df_jes56
)

dat6_3 <- lapply(dat6_3, function(d) {
  list(
    vote_rul = plot6_2df(d, "vote_rul"),
    vote_op  = plot6_2df(d, "vote_op")
  )
})

#----------------------
# プロットの作成と表示
#----------------------
plot_titles <- list(
  all   = list(vote_rul = "全体: 社会志向", vote_op = "全体: 個人志向"),
  jes2  = list(vote_rul = "JES2(99年以前)",  vote_op = "JES2(99年以前)"),
  jes34 = list(vote_rul = "JES3-4(2000年代)", vote_op = "JES3-4(2000年代)"),
  jes56 = list(vote_rul = "JES5-6(2010年代)", vote_op = "JES5-6(2010年代)")
)

plot_list <- list()
for (key in names(dat6_3)) {
  pd <- dat6_3[[key]]
  plot_list[[paste0(key, "_vote_rul")]] <- plot6_2(pd$vote_rul, "vote_rul", plot_titles[[key]]$vote_rul)
  plot_list[[paste0(key, "_vote_op")]]  <- plot6_2(pd$vote_op, "vote_op",   plot_titles[[key]]$vote_op)
}

windows(50, 40)
grid.arrange(
  plot_list$all_vote_rul, plot_list$jes2_vote_rul, plot_list$jes34_vote_rul, plot_list$jes56_vote_rul,
  plot_list$all_vote_op,  plot_list$jes2_vote_op,  plot_list$jes34_vote_op,  plot_list$jes56_vote_op,
  ncol = 4
)

図6-4:所得階層、党派性、個人志向の経済評価

#---------------
# 関数の読み込み
#---------------
source("plot6_4df.R")
source("plot6_4summary.R")
source("plot6_4ttest.R")
source("plot6_4.R")

#--------------
# データの成形
#--------------
dat6_4 <- list(
  all   = list(data = df,      mode = "ego"),
  jes2  = list(data = dfjes2,  mode = "ego"),
  jes34 = list(data = df_jes34, mode = "ego"),
  jes56 = list(data = df_jes56, mode = "ego")
)

dat6_4 <- lapply(dat6_4, function(x) {
  plot6_4df(x$data, x$mode)
})


#----------------------
# プロットの作成と表示
#----------------------
plot_titles <- list(
  all   = "全体",
  jes2  = "JES2(99年以前)",
  jes34 = "JES3-4(2000年代)",
  jes56 = "JES5-6(2010年代)"
)

plots_rul <- lapply(names(dat6_4), function(key) {
  plot6_4(dat6_4[[key]], "ego", plot_titles[[key]], "psu_rul", show_legend = (key == "all"))
})

plots_indep <- lapply(names(dat6_4), function(key) {
  plot6_4(dat6_4[[key]], "ego", plot_titles[[key]], "psu_indep", show_legend = (key == "all"))
})

plot_list <- c(plots_rul, plots_indep)

windows(100, 80)
grid.arrange(
  plot_list[[1]], plot_list[[2]], plot_list[[3]], plot_list[[4]],
  plot_list[[5]], plot_list[[6]], plot_list[[7]], plot_list[[8]],
  ncol = 4
)

図6-5:所得階層、党派性、個人志向の経済評価

#---------------------------------------------
# 関数の読み込み(図6-4作成時と同じ関数を利用)
#---------------------------------------------
source("plot6_4df.R")
source("plot6_4summary.R")
source("plot6_4ttest.R")
source("plot6_4.R")

#--------------
# データの成形
#--------------
dat6_5 <- list(
  all   = list(data = df,      mode = "socio"),
  jes2  = list(data = dfjes2,  mode = "socio"),
  jes34 = list(data = df_jes34, mode = "socio"),
  jes56 = list(data = df_jes56, mode = "socio")
)

dat6_5 <- lapply(dat6_5, function(x) {
  plot6_4df(x$data, x$mode)
})


#----------------------
# プロットの作成と表示
#----------------------
plot_titles <- list(
  all   = "全体",
  jes2  = "JES2(99年以前)",
  jes34 = "JES3-4(2000年代)",
  jes56 = "JES5-6(2010年代)"
)

plots_rul_socio <- lapply(names(dat6_5), function(key) {
  plot6_4(dat6_5[[key]], "socio", plot_titles[[key]], "psu_rul", show_legend = (key == "all"))
})

plots_indep_socio <- lapply(names(dat6_5), function(key) {
  plot6_4(dat6_5[[key]], "socio", plot_titles[[key]], "psu_indep", show_legend = (key == "all"))
})

plot_lists <- c(plots_rul_socio, plots_indep_socio)

windows(100, 80)
grid.arrange(
  plot_lists[[1]], plot_lists[[2]], plot_lists[[3]], plot_lists[[4]],
  plot_lists[[5]], plot_lists[[6]], plot_lists[[7]], plot_lists[[8]],
  ncol = 4
)

図6-6:所得階層、党派性、投票割合

#----------------
# 関数の読み込み
#----------------
source("plot6_6.R")


#--------------
# データの成形
#--------------
dat6_6 <- list(
  all   = plot6_4df(df, "vote_rul"),
  jes2  = plot6_4df(dfjes2, "vote_rul"),
  jes34 = plot6_4df(df_jes34, "vote_rul"),
  jes56 = plot6_4df(df_jes56, "vote_rul")
)

#----------------------
# プロットの作成と表示
#----------------------
plot_titles <- list(
  all   = "全体",
  jes2  = "JES2(99年以前)",
  jes34 = "JES3-4(2000年代)",
  jes56 = "JES5-6(2010年代)"
)

plots_rul <- lapply(names(dat6_6), function(key) {
  plot6_6(dat6_6[[key]], "vote_rul", plot_titles[[key]], "psu_rul", show_legend = (key == "all"))
})

plots_op <- lapply(names(dat6_6), function(key) {
  plot6_6(dat6_6[[key]], "vote_op", plot_titles[[key]], "psu_op", show_legend = (key == "all"))
})

plots_indep <- lapply(names(dat6_6), function(key) {
  plot6_6(dat6_6[[key]], "vote_op", plot_titles[[key]], "psu_indep", show_legend = (key == "all"))
})

plot_list <- c(plots_rul, plots_op, plots_indep)

windows(140, 120)
grid.arrange(
  plot_list[[1]],  plot_list[[2]],  plot_list[[3]],  plot_list[[4]],
  plot_list[[5]],  plot_list[[6]],  plot_list[[7]],  plot_list[[8]],
  plot_list[[9]],  plot_list[[10]], plot_list[[11]], plot_list[[12]],
  ncol = 4
)

図6-7:所得階層のもとでの社会志向の経済評価の上昇程度の党派性差異

###############################
# 与党派と非与党派間での評価差#
###############################


#------------------------
# データの読み込みと設定
#------------------------

results <- list()
years <- c(1983, 2001, 2003, 2004, 2005, 2007, 2009, 2010, 2012, 2013, 2014, 2016, 2017, 2019)
income_levels <- c(1, 2, 3)
dat6_7$income_level <- as.numeric(as.character(dat6_7$income_level))


#-------------------------------------------------------
# 推定とシミュレーションの実行(エラー確認実施も含めて)
#-------------------------------------------------------
for (temp_year in years) {
  for (temp_income_level in income_levels) {
    filtered_df <- df %>% filter(year == temp_year)
    
      result <- tryCatch({
      model <- zelig(socio ~ income_level + educ + employ + interest + age + gender + psu_rul +  ego, 
                     data = filtered_df, model = "normal", cite = "FALSE")
      x.notrul <- setx(model, psu_rul = 0, income_level = temp_income_level)
      x.rul <- setx(model, psu_rul = 1, income_level = temp_income_level)
      s.out <- sim(model, x = x.notrul, x1 = x.rul)
      sim_fd <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
      quantiles <- quantile(sim_fd[,1], c(0.5, .025, .975))
      
      list(mean = quantiles[1], low = quantiles[2], high = quantiles[3])
    }, error = function(e) {
      list(mean = NA, low = NA, high = NA)
    })
    
    results[[paste(temp_year, temp_income_level)]] <- result
  }
}



#------------------------------
# 結果をデータフレームに成形
#------------------------------
results_df <- do.call(rbind, lapply(names(results), function(name) {
  year_income <- strsplit(name, " ")[[1]]
  cbind(年 = as.numeric(year_income[1]), 
        所得階層 = as.numeric(year_income[2]), 
= results[[name]]$mean, 
        下側 = results[[name]]$low, 
        上側 = results[[name]]$high)
}))

results_df <- transform(results_df, 年 = as.integer(年))
results_df$所得階層[results_df$所得階層 == 1] <- "低所得層"
results_df$所得階層[results_df$所得階層 == 2] <- "中所得層"
results_df$所得階層[results_df$所得階層 == 3] <- "高所得層"


#-----------------
# プロットの作成
#-----------------
f1 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と野党派間での評価差") +
  ggtitle("社会志向の経済評価(所得階層)")    +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()



#######################
# 他党派間での評価差 #
#######################

#-------------------------
#他プロットについての説明
#-------------------------

#----野党派と非野党派間の場合、以下のように野党派ダミーをめぐる設定に変更の上でf2を作成
x.notrul <- setx(model, psu_op = 0, income_level = temp_income_level)
x.rul <- setx(model, psu_op = 1, income_level = temp_income_level)

f2 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("野党派と非野党派間での評価差") +
  ggtitle("社会志向の経済評価(所得階層)")    +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()


#----無党派と有党派間の場合、以下のように無党派ダミーをめぐる設定に変更
x.notrul <- setx(model, psu_indep = 0, income_level = temp_income_level)
x.rul <- setx(model, psu_indep = 1, income_level = temp_income_level)

f3 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("無党派と有党派間での投票確率の差") +
  ggtitle("社会志向の経済評価(所得階層)")    +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()


#------------------------
# 最終的なプロットの表示
#------------------------

grid.arrange(f1, f2, f3, ncol = 2)

【補足】OLS推定の結果(与党支持の場合)

以下では、図6-7のベースとなっているOLS推定について、所得階層変数と党派性変数の結果に絞って報告する。

#-------------------
# データの読み込み
#-------------------
dat6_7 <- read.csv("dfjes_zelig.csv") %>%
  mutate(income_level = as.numeric(as.character(income_level))) %>%
  na.omit()

years <- c(2001, 2003, 2004, 2005, 2007, 2009, 2012, 2013, 2014, 2016, 2017, 2019)


#----------------
# OLS推定の設定
#----------------
results_list <- list()

get_stars <- function(p) {
  if (is.na(p)) return("")
  if (p < 0.001) return("***")
  else if (p < 0.01) return("**")
  else if (p < 0.05) return("*")
  else return("")
}

for (yr in years) {
  data_subset <- dat6_7 %>% filter(year == yr)
  if (nrow(data_subset) == 0) {
    next
  }
  
  model <- lm(socio ~ income_level + educ + employ + interest + age + gender + psu_rul + ego,
              data = data_subset)
  sum_model <- summary(model)
  
  n_obs <- nrow(data_subset)
  r2_val <- sum_model$r.squared
  
  coefs <- sum_model$coefficients
  
  inc_cell <- NA
  if ("income_level" %in% rownames(coefs)) {
    inc_est <- coefs["income_level", "Estimate"]
    inc_se  <- coefs["income_level", "Std. Error"]
    inc_p   <- coefs["income_level", "Pr(>|t|)"]
    inc_star <- get_stars(inc_p)
 
    inc_cell <- sprintf("%.3f%s (%.3f)", inc_est, inc_star, inc_se)
  }
  
  rul_cell <- NA
  if ("psu_rul" %in% rownames(coefs)) {
    rul_est <- coefs["psu_rul", "Estimate"]
    rul_se  <- coefs["psu_rul", "Std. Error"]
    rul_p   <- coefs["psu_rul", "Pr(>|t|)"]
    rul_star <- get_stars(rul_p)
    rul_cell <- sprintf("%.3f%s (%.3f)", rul_est, rul_star, rul_se)
  }
  
  nr2_cell <- sprintf("N=%d, R2=%.3f", n_obs, r2_val)
  
  results_list[[as.character(yr)]] <- list(
    income_level = inc_cell,
    psu_rul      = rul_cell,
    nr2          = nr2_cell
  )
}


#-------------------
# OLS推定結果の成形
#-------------------
final_df <- data.frame(
  変数名等 = c("所得階層", "与党支持", "N & R²"),
  stringsAsFactors = FALSE
)

for (yr in names(results_list)) {
  vals <- results_list[[yr]]
  col_data <- c(vals$income_level, vals$psu_rul, vals$nr2)
  final_df[[yr]] <- col_data
}

final_df <- final_df[, c("変数名等", as.character(years))]


#-------------------
# OLS推定結果の表示
#-------------------
tb_ols <- kable(
  final_df,
  format = "html",
  align = "c",
)

調査年ごとのOLS推定結果(与党支持の場合)従属変数:社会志向の経済評価

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.023 (0.064) 0.092 (0.059) 0.363 (0.210) 0.053 (0.073) 0.004 (0.057) 0.047 (0.066) 0.043 (0.032) 0.044 (0.037) 0.007 (0.045) -0.029 (0.062) 0.097 (0.056) 0.003 (0.057)
与党支持 0.225* (0.093) 0.290** (0.092) 0.659 (0.364) 0.346** (0.117) 0.394*** (0.091) -0.015 (0.105) 0.061 (0.072) 0.218*** (0.065) 0.370*** (0.069) 0.514*** (0.097) 0.598*** (0.090) 0.336*** (0.090)
N & R² N=323, R2=0.045 N=399, R2=0.157 N=34, R2=0.455 N=286, R2=0.190 N=394, R2=0.135 N=174, R2=0.160 N=1002, R2=0.067 N=770, R2=0.152 N=562, R2=0.255 N=317, R2=0.149 N=395, R2=0.246 N=391, R2=0.181

【補足】OLS推定の結果(野党支持の場合)

調査年ごとのOLS推定結果(野党支持の場合)従属変数:社会志向の経済評価

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.022 (0.064) 0.091 (0.060) 0.294 (0.220) 0.033 (0.073) 0.011 (0.057) 0.046 (0.066) 0.045 (0.032) 0.047 (0.037) 0.001 (0.046) -0.030 (0.064) 0.075 (0.058) 0.010 (0.058)
野党支持 -0.247* (0.109) -0.138 (0.103) 0.462 (0.397) -0.394** (0.125) -0.534*** (0.099) -0.032 (0.119) 0.063 (0.052) -0.054 (0.071) -0.142 (0.087) -0.435*** (0.127) -0.512*** (0.109) -0.178 (0.115)
N & R² N=323, R2=0.043 N=399, R2=0.139 N=34, R2=0.415 N=286, R2=0.193 N=394, R2=0.156 N=174, R2=0.160 N=1002, R2=0.067 N=770, R2=0.140 N=562, R2=0.220 N=317, R2=0.105 N=395, R2=0.205 N=391, R2=0.157

【補足】OLS推定の結果(無党派の場合)

調査年ごとのOLS推定結果(無党派の場合)従属変数:社会志向の経済評価

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.037 (0.064) 0.097 (0.059) 0.249 (0.193) 0.055 (0.075) 0.005 (0.059) 0.046 (0.066) 0.045 (0.032) 0.041 (0.037) 0.004 (0.045) -0.013 (0.064) 0.097 (0.059) -0.006 (0.058)
無党派 -0.084 (0.136) -0.357** (0.134) -0.911** (0.299) -0.012 (0.203) 0.069 (0.115) 0.053 (0.138) -0.110 (0.056) -0.189** (0.069) -0.283*** (0.071) -0.317** (0.112) -0.384** (0.120) -0.268** (0.100)
N & R² N=323, R2=0.028 N=399, R2=0.151 N=34, R2=0.550 N=286, R2=0.164 N=394, R2=0.094 N=174, R2=0.160 N=1002, R2=0.069 N=770, R2=0.148 N=562, R2=0.238 N=317, R2=0.095 N=395, R2=0.181 N=391, R2=0.167

図6-8:所得階層ごとの個人志向の経済評価の上昇程度の党派性差異

#------------------------------
# 推定とシミュレーションの実行
#------------------------------
#図6-7の作成コードのうち、以下の該当部分のみ変更


for (temp_year in years) {
  for (temp_income_level in income_levels) {
    filtered_df <- df %>% filter(year == temp_year)
    
      result <- tryCatch({
      model <- zelig(ego ~ income_level + educ + employ + interest + age + gender + psu_rul +  ego, 
                     data = filtered_df, model = "normal", cite = "FALSE") #従属変数を変更
      x.notrul <- setx(model, psu_rul = 0, income_level = temp_income_level)
      x.rul <- setx(model, psu_rul = 1, income_level = temp_income_level)
      s.out <- sim(model, x = x.notrul, x1 = x.rul)
      sim_fd <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
      quantiles <- quantile(sim_fd[,1], c(0.5, .025, .975))
      
      list(mean = quantiles[1], low = quantiles[2], high = quantiles[3])
    }, error = function(e) {
      list(mean = NA, low = NA, high = NA)
    })
    
    results[[paste(temp_year, temp_income_level)]] <- result
  }
}


#-----------------
# プロットの作成
#-----------------
f1 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と野党派間での評価差") +
  ggtitle("個人志向の経済評価(所得階層)")    +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()

【補足】OLS推定の結果(与党支持の場合)

以下では、図6-8のベースとなっているOLS推定について、所得階層変数と党派性変数の結果に絞って報告する。

調査年ごとのOLS推定結果(与党支持の場合)従属変数:個人志向の経済評価

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.037 (0.064) 0.097 (0.059) 0.249 (0.193) 0.055 (0.075) 0.005 (0.059) 0.046 (0.066) 0.045 (0.032) 0.041 (0.037) 0.004 (0.045) -0.013 (0.064) 0.097 (0.059) -0.006 (0.058)
無党派 -0.084 (0.136) -0.357** (0.134) -0.911** (0.299) -0.012 (0.203) 0.069 (0.115) 0.053 (0.138) -0.110 (0.056) -0.189** (0.069) -0.283*** (0.071) -0.317** (0.112) -0.384** (0.120) -0.268** (0.100)
N & R² N=323, R2=0.028 N=399, R2=0.151 N=34, R2=0.550 N=286, R2=0.164 N=394, R2=0.094 N=174, R2=0.160 N=1002, R2=0.069 N=770, R2=0.148 N=562, R2=0.238 N=317, R2=0.095 N=395, R2=0.181 N=391, R2=0.167

【補足】OLS推定の結果(野党支持の場合)

調査年ごとのOLS推定結果(野党支持の場合)従属変数:個人志向の経済評価

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.058 (0.053) -0.001 (0.043) 0.328* (0.156) 0.033 (0.049) 0.076 (0.039) -0.029 (0.070) 0.065* (0.027) 0.003 (0.029) 0.141*** (0.040) 0.098 (0.053) 0.138** (0.044) 0.152** (0.050)
野党支持 -0.115 (0.090) -0.152* (0.073) -0.566 (0.283) -0.137 (0.083) -0.183** (0.068) -0.005 (0.127) 0.127** (0.045) -0.035 (0.055) -0.004 (0.077) -0.104 (0.106) 0.017 (0.085) -0.046 (0.100)
N & R² N=323, R2=0.053 N=399, R2=0.048 N=34, R2=0.429 N=286, R2=0.047 N=394, R2=0.041 N=174, R2=0.022 N=1002, R2=0.029 N=770, R2=0.059 N=562, R2=0.083 N=317, R2=0.055 N=395, R2=0.096 N=391, R2=0.079

【補足】OLS推定の結果(無党派の場合)

cat("<p style='text-align:center'><strong>調査年ごとのOLS推定結果(無党派の場合)従属変数:個人志向の経済評価</strong></p>\n")  

調査年ごとのOLS推定結果(無党派の場合)従属変数:個人志向の経済評価

cat(tb_ols_ego)
変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.065 (0.053) 0.002 (0.043) 0.330 (0.166) 0.043 (0.049) 0.074 (0.039) -0.029 (0.070) 0.064* (0.027) -0.000 (0.029) 0.141*** (0.040) 0.102 (0.053) 0.144** (0.044) 0.140** (0.050)
無党派 0.046 (0.112) -0.061 (0.097) 0.209 (0.274) -0.032 (0.134) -0.062 (0.078) -0.032 (0.147) -0.099* (0.048) -0.083 (0.054) -0.168** (0.063) -0.107 (0.093) -0.206* (0.091) -0.234** (0.086)
N & R² N=323, R2=0.048 N=399, R2=0.039 N=34, R2=0.355 N=286, R2=0.038 N=394, R2=0.025 N=174, R2=0.022 N=1002, R2=0.026 N=770, R2=0.062 N=562, R2=0.095 N=317, R2=0.056 N=395, R2=0.107 N=391, R2=0.096

図6-9:所得階層ごとの投票確率の党派性差異

#################################
# 与党派と野党派間での投票確率差#
#################################


#------------------------
# データの読み込みと設定
#------------------------
results <- list()
years <- c(2001, 2003, 2004, 2005, 2007, 2009, 2012, 2013, 2014, 2016, 2017, 2019)
income_levels <- c(1, 2, 3) 



#------------------------------
# 推定とシミュレーションの実行
#------------------------------
for (temp_year in years) {
  for (temp_income_level in income_levels) {
    filtered_df <- dat6_7 %>% filter(year == temp_year)
    result <- tryCatch({
      model <- zelig(vote_rul ~ income_level + educ + employ + interest + age + gender + 
                       psu_rul + socio + ego, 
                       data = filtered_df, model = "logit", cite = "FALSE")
      x.notrul <- setx(model, psu_rul = 0, income_level = temp_income_level)
      x.rul <- setx(model, psu_rul = 1, income_level = temp_income_level)
      s.out <- sim(model, x = x.notrul, x1 = x.rul)
      sim_fd <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
      quantiles <- quantile(sim_fd[,1], c(0.5, .025, .975))
      
      list(mean = quantiles[1], low = quantiles[2], high = quantiles[3])
    }, error = function(e) {
      list(mean = NA, low = NA, high = NA)
    })
    
    results[[paste(temp_year, temp_income_level)]] <- result
  }
}


#------------------------------
# 結果をデータフレームに成形
#------------------------------

results_df <- do.call(rbind, lapply(names(results), function(name) {
  year_income <- strsplit(name, " ")[[1]]
  cbind(年 = as.numeric(year_income[1]), 
        所得階層 = as.numeric(year_income[2]), 
= results[[name]]$mean, 
        下側 = results[[name]]$low, 
        上側 = results[[name]]$high)
}))

results_df <- transform(results_df, 年 = as.integer(年))
results_df$所得階層[results_df$所得階層 == 1] <- "低所得層"
results_df$所得階層[results_df$所得階層 == 2] <- "中所得層"
results_df$所得階層[results_df$所得階層 == 3] <- "高所得層"



#-----------------
# プロットの作成
#-----------------
f1 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と野党派間での投票確率の差") +
  ggtitle("与党投票(所得階層)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()



#######################
# 他党派間での評価差 #
#######################

#-------------------------
#他プロットについての説明
#-------------------------
#該当箇所を下記のように変更することで作図可能

#----野党派と与党派間での野党投票確率の差の場合
model <- zelig(vote_op ~ income_level + educ + employ + interest + age + gender + 
                 psu_op + socio + ego,
                 data = filtered_df, model = "logit", cite = "FALSE")
x.notrul <- setx(model, psu_op = 0, income_level = temp_income_level)
x.rul <- setx(model, psu_op = 1, income_level = temp_income_level)

f2 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と野党派間での投票確率の差") +
  ggtitle("野党投票(所得階層)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()



#----与党派と無党派間での与党投票の場合
model <- zelig(vote_rul ~ income_level + educ + employ + interest + age + gender + 
                 psu_indep + socio + ego, 
                 data = filtered_df, model = "logit", cite = "FALSE")
x.notrul <- setx(model, psu_indep = 0, income_level = temp_income_level)
x.rul <- setx(model, psu_indep = 1, income_level = temp_income_level)

f3 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と無党派間での投票確率の差") +
  ggtitle("与党投票(所得階層)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()


#----野党派と無党派間での野党投票の場合
model <- zelig(vote_op ~ income_level + educ + employ + interest + age + gender + 
                 psu_indep + socio + ego, 
                data = filtered_df, model = "logit", cite = "FALSE")
x.notrul <- setx(model, psu_indep = 0, income_level = temp_income_level)
x.rul <- setx(model, psu_indep = 1, income_level = temp_income_level)

f4 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 所得階層,  
                             group = 所得階層, fill = 所得階層)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("野党派と無党派間での投票確率の差") +
  ggtitle("野党投票(所得階層)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()



grid.arrange(f1, f2, f3, f4, ncol = 2)

【補足】ロジスティック回帰の結果(与党支持者の与党投票の場合)

以下では、図6-9のベースとなっているロジスティック回帰について、所得階層変数と党派性変数の結果に絞って報告する。

#---------------------------
# データの読み込みと前処理
#---------------------------
dat6_7 <- read.csv("dfjes_zelig.csv") %>%
  mutate(income_level = as.numeric(as.character(income_level))) %>%
  na.omit()

years <- c(2001, 2003, 2004, 2005, 2007, 2009, 2012, 2013, 2014, 2016, 2017, 2019)

#-------------------------
# ロジスティック回帰の設定
#-------------------------
get_stars <- function(p) {
  if (is.na(p)) return("")
  if (p < 0.001) return("***")
  else if (p < 0.01) return("**")
  else if (p < 0.05) return("*")
  else return("")
}

results_list <- list()

for (yr in years) {
  data_subset <- dat6_7 %>% filter(year == yr)
  if(nrow(data_subset) == 0) next
  
  model <- glm(vote_rul ~ income_level + educ + employ + interest + age + gender + 
                 psu_rul + socio + ego,
                  data = data_subset, family = binomial)
  sum_model <- summary(model)
  
  n_obs <- nrow(data_subset)
  null_model <- glm(vote_rul ~ 1, data = data_subset, family = binomial)
  mcfadden_r2 <- 1 - as.numeric(logLik(model)/logLik(null_model))
  
  coefs <- sum_model$coefficients
  
  inc_cell <- if("income_level" %in% rownames(coefs)) {
    inc_est <- coefs["income_level", "Estimate"]
    inc_se  <- coefs["income_level", "Std. Error"]
    inc_p   <- coefs["income_level", "Pr(>|z|)"]
    sprintf("%.3f%s (%.3f)", inc_est, get_stars(inc_p), inc_se)
  } else { NA }
  
  rul_cell <- if("psu_rul" %in% rownames(coefs)) {
    rul_est <- coefs["psu_rul", "Estimate"]
    rul_se  <- coefs["psu_rul", "Std. Error"]
    rul_p   <- coefs["psu_rul", "Pr(>|z|)"]
    sprintf("%.3f%s (%.3f)", rul_est, get_stars(rul_p), rul_se)
  } else { NA }
  
  nr2_cell <- sprintf("N=%d, R²=%.3f", n_obs, mcfadden_r2)
  
  results_list[[as.character(yr)]] <- list(
    income_level = inc_cell,
    psu_rul = rul_cell,
    nr2 = nr2_cell
  )
}


#-----------------------------------
# ロジスティック回帰の推定結果の成形
#-----------------------------------
final_table <- data.frame(変数名等 = c("所得階層", "与党支持", "N & R²"), stringsAsFactors = FALSE)
for (yr in years) {
  res <- results_list[[as.character(yr)]]
  if (is.null(res)) {
    col_data <- c(NA, NA, NA)
  } else {
    col_data <- c(res$income_level, res$psu_rul, res$nr2)
  }
  final_table[[as.character(yr)]] <- col_data
}
final_table <- final_table[, c("変数名等", as.character(years))]

#-----------
# 表の作成
#-----------
tb_logit <- kable(final_table, format = "html", align = "c")

調査年ごとのロジスティック回帰の推定結果(与党支持の場合)従属変数:与党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.267 (0.188) 0.099 (0.187) -0.060 (1.015) 0.640** (0.224) 0.032 (0.157) -0.151 (0.235) 0.023 (0.082) -0.033 (0.100) -0.000 (0.131) 0.343 (0.191) 0.103 (0.192) 0.014 (0.167)
与党支持 1.821*** (0.266) 2.966*** (0.288) 4.288* (1.876) 2.625*** (0.333) 2.349*** (0.255) 2.794*** (0.472) -1.804*** (0.225) 1.754*** (0.181) 1.753*** (0.223) 2.772*** (0.333) 2.956*** (0.310) 2.491*** (0.266)
N & R² N=323, R²=0.162 N=399, R²=0.327 N=34, R²=0.370 N=286, R²=0.281 N=394, R²=0.230 N=174, R²=0.263 N=1002, R²=0.074 N=770, R²=0.145 N=562, R²=0.150 N=317, R²=0.303 N=395, R²=0.377 N=391, R²=0.270

【補足】ロジスティック回帰の結果(野党支持者の野党投票の場合)

調査年ごとのロジスティック回帰の推定結果(野党支持の場合)従属変数:野党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 -0.242 (0.188) -0.042 (0.186) 0.217 (0.754) -0.439* (0.220) -0.034 (0.148) 0.135 (0.214) -0.044 (0.083) -0.001 (0.096) 0.003 (0.123) -0.289 (0.174) 0.117 (0.181) -0.088 (0.151)
野党支持 2.426*** (0.358) 3.485*** (0.374) 1.296 (1.412) 2.933*** (0.380) 2.344*** (0.347) 2.615*** (0.638) -1.351*** (0.137) 1.243*** (0.183) 0.924*** (0.225) 2.874*** (0.449) 2.596*** (0.325) 1.969*** (0.328)
N & R² N=323, R²=0.181 N=399, R²=0.332 N=34, R²=0.164 N=286, R²=0.290 N=394, R²=0.169 N=174, R²=0.154 N=1002, R²=0.090 N=770, R²=0.093 N=562, R²=0.076 N=317, R²=0.238 N=395, R²=0.295 N=391, R²=0.153

【補足】ロジスティック回帰の結果(無党派の与党投票の場合)

調査年ごとのロジスティック回帰の推定結果(無党派の場合)従属変数:与党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 0.337 (0.174) 0.065 (0.153) -0.574 (1.062) 0.473* (0.187) 0.007 (0.138) -0.097 (0.214) 0.017 (0.079) -0.035 (0.094) -0.008 (0.124) 0.343* (0.166) 0.004 (0.161) -0.045 (0.150)
無党派 -0.427 (0.354) -0.337 (0.332) -6.809* (3.429) -0.198 (0.480) -1.084*** (0.295) -2.235*** (0.668) -0.565*** (0.141) -0.642*** (0.173) -0.895*** (0.192) -1.155*** (0.286) -1.075*** (0.309) -1.329*** (0.257)
N & R² N=323, R²=0.049 N=399, R²=0.068 N=34, R²=0.382 N=286, R²=0.079 N=394, R²=0.069 N=174, R²=0.112 N=1002, R²=0.027 N=770, R²=0.060 N=562, R²=0.083 N=317, R²=0.123 N=395, R²=0.162 N=391, R²=0.125

【補足】ロジスティック回帰の結果(無党派の野党投票の場合)

調査年ごとのロジスティック回帰の推定結果(無党派の場合)従属変数:野党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
所得階層 -0.337 (0.174) -0.065 (0.153) 0.574 (1.062) -0.473* (0.187) 0.015 (0.138) 0.059 (0.212) -0.017 (0.079) 0.035 (0.094) 0.008 (0.124) -0.351* (0.164) -0.004 (0.161) 0.045 (0.150)
無党派 0.427 (0.354) 0.337 (0.332) 6.809* (3.429) 0.198 (0.480) 1.049*** (0.293) 2.216*** (0.662) 0.565*** (0.141) 0.642*** (0.173) 0.895*** (0.192) 0.996*** (0.285) 1.075*** (0.309) 1.329*** (0.257)
N & R² N=323, R²=0.049 N=399, R²=0.068 N=34, R²=0.382 N=286, R²=0.079 N=394, R²=0.074 N=174, R²=0.102 N=1002, R²=0.027 N=770, R²=0.060 N=562, R²=0.083 N=317, R²=0.123 N=395, R²=0.162 N=391, R²=0.125

第7章:党派性、経済評価は投票選択を決めるのか?―観察データの分析(2)

本文の補足分析と各図表のコード

図7-2:社会志向の経済評価と投票選択

図7-4については、以下のコードをのsocio変数をego変数に、「社会志向」の表記を「個人志向」に改めることで再現可能である。

#----------------
# 関数の読み込み
#----------------
source("plot7_2df.R")
source("plot7_2.R")

#------------------
# データの読み込み
#------------------
file_names <- c("JES_whole.csv", "dfjes2.csv", "dfjes3.csv", "dfjes4.csv", "dfjes5.csv", "dfjes6.csv")
data_labels <- c("whole", "jes2", "jes3", "jes4", "jes5", "jes6")

data_list <- setNames(lapply(file_names, read.csv), data_labels)

df_34 <- rbind(data_list$jes3, data_list$jes4)
df_56 <- rbind(data_list$jes5, data_list$jes6)

dat7_2 <- list(
  whole = data_list$whole,
  jes2  = data_list$jes2,
  jes34 = df_34,
  jes56 = df_56
)

#-------------
# データの成形
#-------------
dat7_2 <- lapply(dat7_2, function(df) {
  list(
    vote_rul = plot7_2df(df, "vote_rul", title = "与党投票"),
    vote_op  = plot7_2df(df, "vote_op", title = "野党投票")
  )
})

#----------------------
# プロットの作成と表示
#----------------------
plot_titles <- list(
  whole = list(vote_rul = "全体: 与党投票", vote_op = "全体: 野党投票"),
  jes2  = list(vote_rul = "JES2(99年以前)",  vote_op = "JES2(99年以前)"),
  jes34 = list(vote_rul = "JES3-4(2000年代)", vote_op = "JES3-4(2000年代)"),
  jes56 = list(vote_rul = "JES5-6(2010年代)", vote_op = "JES5-6(2010年代)")
)

plot_list <- list()
for (key in names(dat7_2)) {
  proc <- dat7_2[[key]]
  plot_list[[paste0(key, "_vote_rul")]] <- plot7_2(proc$vote_rul, "vote_rul", plot_titles[[key]]$vote_rul)
  plot_list[[paste0(key, "_vote_op")]]  <- plot7_2(proc$vote_op, "vote_op", plot_titles[[key]]$vote_op)
}

windows(50, 40)
grid.arrange(
  plot_list$whole_vote_rul, plot_list$jes2_vote_rul, plot_list$jes34_vote_rul, plot_list$jes56_vote_rul,
  plot_list$whole_vote_op,  plot_list$jes2_vote_op,  plot_list$jes34_vote_op,  plot_list$jes56_vote_op,
  ncol = 4
)

【補足】ロジスティック回帰推定の結果(与党支持者の与党投票の場合)

以下では、図6-7のベースとなっているロジスティック回帰分析について、所得階層変数と党派性変数の結果に絞って報告する。

#---------------------------
# データの読み込みと前処理
#---------------------------
dat7_2 <- read.csv("dfjes_zelig.csv") %>%
  mutate(income_level = as.numeric(as.character(income_level))) %>%
  na.omit()

years <- c(2001, 2003, 2004, 2005, 2007, 2009, 2012, 2013, 2014, 2016, 2017, 2019)

#-------------------------
# ロジスティック回帰の設定
#-------------------------
get_stars <- function(p) {
  if (is.na(p)) return("")
  if (p < 0.001) return("***")
  else if (p < 0.01) return("**")
  else if (p < 0.05) return("*")
  else return("")
}

results_list <- list()

for (yr in years) {
  data_subset <- dat7_2 %>% filter(year == yr)
  if(nrow(data_subset) == 0) next
  
  model <- glm(vote_rul ~ income_level + educ + employ + interest + age + gender + 
                 psu_rul + socio + ego,
                  data = data_subset, family = binomial)
  sum_model <- summary(model)
  
  n_obs <- nrow(data_subset)
  null_model <- glm(vote_rul ~ 1, data = data_subset, family = binomial)
  mcfadden_r2 <- 1 - as.numeric(logLik(model)/logLik(null_model))
  
  coefs <- sum_model$coefficients
  
    inc_cell <- if("socio" %in% rownames(coefs)) {
    inc_est <- coefs["socio", "Estimate"]
    inc_se  <- coefs["socio", "Std. Error"]
    inc_p   <- coefs["socio", "Pr(>|z|)"]
    sprintf("%.3f%s (%.3f)", inc_est, get_stars(inc_p), inc_se)
  } else { NA }
  
  
    ego_cell <- if("ego" %in% rownames(coefs)) {
    ego_est <- coefs["ego", "Estimate"]
    ego_se  <- coefs["ego", "Std. Error"]
    ego_p   <- coefs["ego", "Pr(>|z|)"]
    sprintf("%.3f%s (%.3f)", ego_est, get_stars(inc_p), inc_se)
  } else { NA }
    
    
  rul_cell <- if("psu_rul" %in% rownames(coefs)) {
    rul_est <- coefs["psu_rul", "Estimate"]
    rul_se  <- coefs["psu_rul", "Std. Error"]
    rul_p   <- coefs["psu_rul", "Pr(>|z|)"]
    sprintf("%.3f%s (%.3f)", rul_est, get_stars(rul_p), rul_se)
  } else { NA }
  
  nr2_cell <- sprintf("N=%d, R²=%.3f", n_obs, mcfadden_r2)
  
  results_list[[as.character(yr)]] <- list(
    socio = inc_cell,
    ego = ego_cell,
    psu_rul = rul_cell,
    nr2 = nr2_cell
  )
}


#-----------------------------------
# ロジスティック回帰の推定結果の成形
#-----------------------------------
final_table <- data.frame(変数名等 = c("社会志向", "個人志向",  "与党支持", "N & R²"), stringsAsFactors = FALSE)
for (yr in years) {
  res <- results_list[[as.character(yr)]]
  if (is.null(res)) {
    col_data <- c(NA, NA, NA)
  } else {
    col_data <- c(res$socio, res$ego, res$psu_rul, res$nr2)
  }
  final_table[[as.character(yr)]] <- col_data
}
final_table <- final_table[, c("変数名等", as.character(years))]

#-----------
# 表の作成
#-----------
tb_logitsc <- kable(final_table, format = "html", align = "c")

調査年ごとのロジスティック回帰の推定結果(与党支持の場合)従属変数:与党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
社会志向 -0.013 (0.162) 0.078 (0.163) -1.683 (1.075) 0.236 (0.169) 0.233 (0.136) 0.151 (0.282) 0.001 (0.082) 0.085 (0.099) 0.333** (0.123) 0.334 (0.176) 0.439** (0.166) 0.464** (0.151)
個人志向 -0.025 (0.162) 0.052 (0.163) -0.362 (1.075) 0.458 (0.169) 0.015 (0.136) 0.138 (0.282) 0.001 (0.082) -0.111 (0.099) -0.023** (0.123) 0.117 (0.176) -0.098** (0.166) -0.138** (0.151)
与党支持 1.821*** (0.266) 2.966*** (0.288) 4.288* (1.876) 2.625*** (0.333) 2.349*** (0.255) 2.794*** (0.472) -1.804*** (0.225) 1.754*** (0.181) 1.753*** (0.223) 2.772*** (0.333) 2.956*** (0.310) 2.491*** (0.266)
N & R² N=323, R²=0.162 N=399, R²=0.327 N=34, R²=0.370 N=286, R²=0.281 N=394, R²=0.230 N=174, R²=0.263 N=1002, R²=0.074 N=770, R²=0.145 N=562, R²=0.150 N=317, R²=0.303 N=395, R²=0.377 N=391, R²=0.270

【補足】ロジスティック回帰推定の結果(無党派の与党投票の場合)

調査年ごとのロジスティック回帰の推定結果(無党派の場合)従属変数:与党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
社会志向 0.128 (0.151) 0.277* (0.133) -2.969 (1.763) 0.395** (0.144) 0.452*** (0.120) 0.111 (0.245) -0.038 (0.080) 0.157 (0.093) 0.435*** (0.118) 0.576*** (0.153) 0.723*** (0.141) 0.526*** (0.134)
個人志向 0.048 (0.151) 0.195* (0.133) 2.270 (1.763) 0.461** (0.144) 0.172*** (0.120) 0.153 (0.245) 0.019 (0.080) -0.053 (0.093) -0.029*** (0.118) 0.131*** (0.153) -0.124*** (0.141) -0.047*** (0.134)
無党派 -0.427 (0.354) -0.337 (0.332) -6.809* (3.429) -0.198 (0.480) -1.084*** (0.295) -2.235*** (0.668) -0.565*** (0.141) -0.642*** (0.173) -0.895*** (0.192) -1.155*** (0.286) -1.075*** (0.309) -1.329*** (0.257)
N & R² N=323, R²=0.049 N=399, R²=0.068 N=34, R²=0.382 N=286, R²=0.079 N=394, R²=0.069 N=174, R²=0.112 N=1002, R²=0.027 N=770, R²=0.060 N=562, R²=0.083 N=317, R²=0.123 N=395, R²=0.162 N=391, R²=0.125

【補足】ロジスティック回帰推定の結果(野党支持者の野党投票の場合)

調査年ごとのロジスティック回帰の推定結果(野党支持の場合)従属変数:野党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
社会志向 0.020 (0.162) -0.281 (0.165) 0.229 (0.567) -0.212 (0.168) -0.252 (0.130) -0.047 (0.265) 0.053 (0.083) -0.179 (0.094) -0.493*** (0.117) -0.542*** (0.164) -0.647*** (0.156) -0.594*** (0.139)
個人志向 0.030 (0.162) -0.021 (0.165) 0.042 (0.567) -0.493 (0.168) -0.132 (0.130) -0.050 (0.265) 0.041 (0.083) 0.053 (0.094) 0.001*** (0.117) -0.229*** (0.164) -0.067*** (0.156) -0.019*** (0.139)
野党支持 2.426*** (0.358) 3.485*** (0.374) 1.296 (1.412) 2.933*** (0.380) 2.344*** (0.347) 2.615*** (0.638) -1.351*** (0.137) 1.243*** (0.183) 0.924*** (0.225) 2.874*** (0.449) 2.596*** (0.325) 1.969*** (0.328)
N & R² N=323, R²=0.181 N=399, R²=0.332 N=34, R²=0.164 N=286, R²=0.290 N=394, R²=0.169 N=174, R²=0.154 N=1002, R²=0.090 N=770, R²=0.093 N=562, R²=0.076 N=317, R²=0.238 N=395, R²=0.295 N=391, R²=0.153

【補足】ロジスティック回帰推定の結果(無党派の野党投票の場合)

調査年ごとのロジスティック回帰の推定結果(無党派の場合)従属変数:野党投票

変数名等 2001 2003 2004 2005 2007 2009 2012 2013 2014 2016 2017 2019
社会志向 -0.128 (0.151) -0.277* (0.133) 2.969 (1.763) -0.395** (0.144) -0.489*** (0.120) -0.100 (0.243) 0.038 (0.080) -0.157 (0.093) -0.435*** (0.118) -0.593*** (0.151) -0.723*** (0.141) -0.526*** (0.134)
個人志向 -0.048 (0.151) -0.195* (0.133) -2.270 (1.763) -0.461** (0.144) -0.200*** (0.120) -0.063 (0.243) -0.019 (0.080) 0.053 (0.093) 0.029*** (0.118) -0.142*** (0.151) 0.124*** (0.141) 0.047*** (0.134)
無党派 0.427 (0.354) 0.337 (0.332) 6.809* (3.429) 0.198 (0.480) 1.049*** (0.293) 2.216*** (0.662) 0.565*** (0.141) 0.642*** (0.173) 0.895*** (0.192) 0.996*** (0.285) 1.075*** (0.309) 1.329*** (0.257)
N & R² N=323, R²=0.049 N=399, R²=0.068 N=34, R²=0.382 N=286, R²=0.079 N=394, R²=0.074 N=174, R²=0.102 N=1002, R²=0.027 N=770, R²=0.060 N=562, R²=0.083 N=317, R²=0.123 N=395, R²=0.162 N=391, R²=0.125

図7-3:社会志向の経済評価、党派性、投票の割合

図7-5については、以下のコードをのsocio変数をego変数に、「社会志向」の表記を「個人志向」に改めることで再現可能である。

#----------------
# 関数の読み込み
#----------------
source("plot7_3df.R")
source("plot7_3.R")

#------------------
# データの読み込み
#------------------
file_names <- c("JES_whole.csv", "dfjes2.csv", "dfjes3.csv", "dfjes4.csv", "dfjes5.csv", "dfjes6.csv")
data_labels <- c("whole", "jes2", "jes3", "jes4", "jes5", "jes6")

data_list <- setNames(lapply(file_names, read.csv), data_labels)

df_34 <- rbind(data_list$jes3, data_list$jes4)
df_56 <- rbind(data_list$jes5, data_list$jes6)

dat7_3 <- list(
  whole = data_list$whole,
  jes2  = data_list$jes2,
  jes34 = df_34,
  jes56 = df_56
)


#-------------
# データの成形
#-------------
dat7_3 <- lapply(dat7_3, function(df) {
  list(
    vote_rul = plot7_3df(df, "vote_rul"),
    vote_op  = plot7_3df(df, "vote_op")
  )
})

#----------------------
# プロットの作成と表示
#----------------------
plot_titles <- list(
  whole = list(vote_rul = "全体: 与党投票", vote_op = "全体: 野党投票"),
  jes2  = list(vote_rul = "JES2(99年以前)",  vote_op = "JES2(99年以前)"),
  jes34 = list(vote_rul = "JES3-4(2000年代)", vote_op = "JES3-4(2000年代)"),
  jes56 = list(vote_rul = "JES5-6(2010年代)", vote_op = "JES5-6(2010年代)")
)

plot_list <- list()
for (key in names(dat7_3)) {
  proc <- dat7_3[[key]]
  plot_list[[paste0(key, "_vote_rul")]] <- plot7_3(proc$vote_rul, "vote_rul", plot_titles[[key]]$vote_rul, "psu_rul", show_legend = TRUE)
  plot_list[[paste0(key, "_vote_op")]]  <- plot7_3(proc$vote_op, "vote_op", plot_titles[[key]]$vote_op, "psu_op", show_legend = FALSE)
}

plot_list[["whole_indep"]] <- plot7_3(dat7_3$whole$vote_op, "vote_op", "全体: 投票(無党派)", "psu_indep", show_legend = TRUE)
plot_list[["jes2_indep"]]  <- plot7_3(dat7_3$jes2$vote_op, "vote_op", "JES2(99年以前): 投票(無党派)", "psu_indep", show_legend = FALSE)
plot_list[["jes34_indep"]] <- plot7_3(dat7_3$jes34$vote_op, "vote_op", "JES3-4(2000年代): 投票(無党派)", "psu_indep", show_legend = FALSE)
plot_list[["jes56_indep"]] <- plot7_3(dat7_3$jes56$vote_op, "vote_op", "JES5-6(2010年代): 投票(無党派)", "psu_indep", show_legend = FALSE)

#----------------------
# プロットの配置
#----------------------
windows(120, 90)
grid.arrange(
  plot_list$whole_vote_rul, plot_list$jes2_vote_rul, plot_list$jes34_vote_rul, plot_list$jes56_vote_rul,
  plot_list$whole_vote_op,  plot_list$jes2_vote_op,  plot_list$jes34_vote_op,  plot_list$jes56_vote_op,
  plot_list$whole_indep,     plot_list$jes2_indep,     plot_list$jes34_indep,     plot_list$jes56_indep,
  ncol = 4
)

図7-6:党派性と社会志向の経済評価の内生性に対処する2段階最小二乗法推定の結果(与党派と野党派の場合)

#----------------
# 関数の読み込み
#----------------
source("plot7_6.R")

#----------------
# 2SLS推定の実行
#----------------
datasets <- list(df = df, dfjes2 = dfjes2, dfjes34 = df_jes34, dfjes56 = df_jes56)
all_results <- list()

for (dataset_name in names(datasets)) {
  all_results[[paste(dataset_name, "vote_rul", sep = "_")]] <- plot7_6(datasets[[dataset_name]], "vote_rul")
  all_results[[paste(dataset_name, "vote_op", sep = "_")]] <- plot7_6(datasets[[dataset_name]], "vote_op")
}

#--------------------
# 2SLS推定結果の整理
#--------------------
df_2sls <- rbind(
all_results[["df_vote_rul"]][["second_stage"]],
all_results[["dfjes2_vote_rul"]][["second_stage"]],
all_results[["dfjes34_vote_rul"]][["second_stage"]],
all_results[["dfjes56_vote_rul"]][["second_stage"]],
all_results[["df_vote_op"]][["second_stage"]],
all_results[["dfjes2_vote_op"]][["second_stage"]],
all_results[["dfjes34_vote_op"]][["second_stage"]],
all_results[["dfjes56_vote_op"]][["second_stage"]])


df_2sls <- df_2sls
df_2sls <- df_2sls %>%
  filter(term %in% c("psu_rul","psu_op", "residuals_1st", "ego"))

時期 <- rep(c("全体", "99年以前(JES2)", "2000年代(JES3-4)", "2010年代(JES5-6)"), each = 3)
period_sequence <- rep(時期, length.out = 24)
df_2sls$時期 <- period_sequence

従属変数 <- rep(c("与党投票", "野党投票"), each = 12)
vote_sequence <- rep(従属変数, length.out = 24)
df_2sls$従属変数 <- vote_sequence

df_2sls$下側 <- df_2sls$estimate - 1.96 * df_2sls$std.error
df_2sls$上側 <- df_2sls$estimate + 1.96 * df_2sls$std.error

colnames(df_2sls) <- c("変数名", "係数", "標準誤差", "統計量", "p値", "時期","従属変数", "下側", "上側")

df_2sls$変数名[df_2sls$変数名 == "psu_rul"] <- "与党支持"
df_2sls$変数名[df_2sls$変数名 == "psu_op"] <- "野党支持"
df_2sls$変数名[df_2sls$変数名 == "residuals_1st"] <- "社会志向"
df_2sls$変数名[df_2sls$変数名 == "ego"] <- "個人志向"

2段階最小二乗法の推定結果

変数名 係数 標準誤差 統計量 p値 時期 従属変数 下側 上側
与党支持 0.412 0.013 32.899 0.000 全体 与党投票 0.387 0.436
社会志向 0.038 0.007 5.757 0.000 全体 与党投票 0.025 0.051
個人志向 0.027 0.008 3.198 0.001 全体 与党投票 0.010 0.043
与党支持 0.591 0.055 10.824 0.000 99年以前(JES2) 与党投票 0.484 0.698
社会志向 0.010 0.027 0.384 0.701 99年以前(JES2) 与党投票 -0.043 0.064
個人志向 -0.031 0.028 -1.111 0.268 99年以前(JES2) 与党投票 -0.086 0.024
与党支持 0.547 0.019 28.258 0.000 2000年代(JES3-4) 与党投票 0.509 0.584
社会志向 0.014 0.010 1.367 0.172 2000年代(JES3-4) 与党投票 -0.006 0.034
個人志向 0.016 0.015 1.054 0.292 2000年代(JES3-4) 与党投票 -0.014 0.045
与党支持 0.305 0.017 17.555 0.000 2010年代(JES5-6) 与党投票 0.271 0.339
社会志向 0.047 0.009 4.963 0.000 2010年代(JES5-6) 与党投票 0.028 0.065
個人志向 0.018 0.011 1.642 0.101 2010年代(JES5-6) 与党投票 -0.004 0.041
野党支持 0.304 0.014 22.452 0.000 全体 野党投票 0.277 0.330
社会志向 -0.039 0.007 -5.609 0.000 全体 野党投票 -0.052 -0.025
個人志向 -0.048 0.009 -5.550 0.000 全体 野党投票 -0.065 -0.031
野党支持 0.591 0.055 10.824 0.000 99年以前(JES2) 野党投票 0.484 0.698
社会志向 -0.010 0.027 -0.384 0.701 99年以前(JES2) 野党投票 -0.064 0.043
個人志向 0.031 0.028 1.111 0.268 99年以前(JES2) 野党投票 -0.024 0.086
野党支持 0.550 0.022 25.296 0.000 2000年代(JES3-4) 野党投票 0.508 0.593
社会志向 -0.016 0.011 -1.514 0.130 2000年代(JES3-4) 野党投票 -0.037 0.005
個人志向 -0.027 0.015 -1.753 0.080 2000年代(JES3-4) 野党投票 -0.057 0.003
野党支持 0.063 0.028 2.299 0.022 2010年代(JES5-6) 野党投票 0.009 0.117
社会志向 -0.061 0.014 -4.255 0.000 2010年代(JES5-6) 野党投票 -0.089 -0.033
個人志向 -0.033 0.017 -1.940 0.052 2010年代(JES5-6) 野党投票 -0.066 0.000
#--------------- 
# プロットの作成
#---------------

#---- 与党投票の図
rul_2sls <- subset(df_2sls, 従属変数 == "与党投票")
rul_2sls <- transform(rul_2sls, 時期=factor(時期, levels=c("全体", "99年以前(JES2)", "2000年代(JES3-4)", "2010年代(JES5-6)")))

rul_2sls$highlight <- with(rul_2sls, (下側 > 0 & 上側 > 0) | (下側 < 0 & 上側 < 0))

g1 <- ggplot(rul_2sls, aes(x = 変数名, y = as.numeric(係数))) +
    geom_point(aes(x = 変数名, y = as.numeric(係数)), fill = "white", color = "black", 
               shape = 21, size = 3) + 
    
    geom_rect(data = subset(rul_2sls, highlight == TRUE),
              aes(xmin = as.numeric(factor(変数名)) - 0.4, xmax = as.numeric(factor(変数名)) + 0.4, 
                  ymin = 下側, ymax = 上側), fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
    
    geom_errorbar(aes(x = 変数名, ymin = as.numeric(下側), ymax = as.numeric(上側), width = 0.1)) +
    
    geom_text(data = subset(rul_2sls, highlight == TRUE),
              aes(label = paste0(round(係数, 2), "\n[", round(下側, 2), ", ", round(上側, 2), "]")),
              nudge_y = ifelse(as.numeric(rul_2sls$係数) > 0, 0.02, -0.02), size = 3.5, 
              color = "black") +
    
    ggtitle("与党への投票に関する2SLSの結果") +
    facet_wrap(時期 ~ ., scales = "free", ncol = 1) +
    coord_flip() +
    theme_bw() +
    geom_hline(yintercept = 0, colour = gray(1/2), lty = 2) +
    ylab("係数")

#---- 野党投票の図
op_2sls <- subset(df_2sls, 従属変数 == "野党投票")
op_2sls <- transform(op_2sls, 時期=factor(時期, levels=c("全体", "99年以前(JES2)", "2000年代(JES3-4)", "2010年代(JES5-6)")))

op_2sls$highlight <- with(op_2sls, (下側 > 0 & 上側 > 0) | (下側 < 0 & 上側 < 0))

g2 <- ggplot(op_2sls, aes(x = 変数名, y = as.numeric(係数))) +
  geom_point(aes(x = 変数名, y = as.numeric(係数)), fill = "white", color = "black", shape = 21, size = 3) + 
  
  geom_rect(data = subset(op_2sls, highlight == TRUE),
            aes(xmin = as.numeric(factor(変数名)) - 0.4, xmax = as.numeric(factor(変数名)) + 0.4, 
                ymin = 下側, ymax = 上側), fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
  
  geom_errorbar(aes(x = 変数名, ymin = as.numeric(下側), ymax = as.numeric(上側), width = 0.1)) +
  
  geom_text(data = subset(op_2sls, highlight == TRUE),
            aes(label = paste0(round(係数, 2), "\n[", round(下側, 2), ", ", round(上側, 2), "]")),
            nudge_y = ifelse(as.numeric(op_2sls$係数) > 0, 0.02, -0.02), size = 3.5, color = "black") +
  
  ggtitle("野党への投票に関する2SLSの結果") +
  facet_wrap(時期 ~ ., scales = "free", ncol = 1) +
  coord_flip() +
  theme_bw() +
  geom_hline(yintercept = 0, colour = gray(1/2), lty = 2) +
  ylab("係数")

windows(65,60)
grid.arrange(g1, g2, ncol = 2)

図7-7:所得階層ごとの投票確率の党派性差異

#################################
# 与党派と野党派間での投票確率差#
#################################


#------------------------
# データの読み込みと設定
#------------------------
results <- list()
years <- c(1983, 2001, 2003, 2004, 2005, 2007, 2009, 2010, 2012, 2013, 2014, 2016, 2017, 2019)
income_levels <- c(1, 2, 3) 



#------------------------------
# 推定とシミュレーションの実行
#------------------------------
for (temp_year in years) {
  for (temp_income_level in income_levels) {
    filtered_df <- dat6_7 %>% filter(year == temp_year)
    result <- tryCatch({
      model <- zelig(vote_rul ~ income_level + educ + employ + interest + age + gender + 
                       psu_rul + socio + ego, 
                       data = filtered_df, model = "logit", cite = "FALSE")
      x.notrul <- setx(model, psu_rul = 0, socio_level = temp_socio_level)
      x.rul <- setx(model, psu_rul = 1, socio_level = temp_socio_level)
      s.out <- sim(model, x = x.notrul, x1 = x.rul)
      sim_fd <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
      quantiles <- quantile(sim_fd[,1], c(0.5, .025, .975))
      
      list(mean = quantiles[1], low = quantiles[2], high = quantiles[3])
    }, error = function(e) {
      list(mean = NA, low = NA, high = NA)
    })
    
    results[[paste(temp_year, temp_socio_level)]] <- result
  }
}


#------------------------------
# 結果をデータフレームに成形
#------------------------------

results_df <- do.call(rbind, lapply(names(results), function(name) {
  year_socio <- strsplit(name, " ")[[1]]
  cbind(年 = as.numeric(year_socio[1]), 
        社会志向 = as.numeric(year_socio[2]), 
= results[[name]]$mean, 
        下側 = results[[name]]$low, 
        上側 = results[[name]]$high)
}))

# 列の型を適切に設定
results_df <- transform(results_df, 年 = as.integer(年))
results_df$社会志向[results_df$社会志向 == 1] <- "低評価"
results_df$社会志向[results_df$社会志向 == 2] <- "中評価"
results_df$社会志向[results_df$社会志向 == 3] <- "高評価"



#-----------------
# プロットの作成
#-----------------
g1 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 社会志向,  
                             group = 社会志向, fill = 社会志向)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と野党派間での投票確率の差") +
  ggtitle("与党投票(社会志向)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()




#######################
# 他党派間での評価差 #
#######################

#-------------------------
#他プロットについての説明
#-------------------------
#該当箇所を下記のように変更することで作図可能

#----野党派と与党派間での野党投票確率の差の場合
model <- zelig(vote_op ~ socio_level + educ + employ + interest + age + gender + 
                 psu_op + ego + income, 
                     data = filtered_df, model = "logit", cite = "FALSE")
x.notrul <- setx(model, psu_op = 0, socio_level = temp_socio_level)
x.rul <- setx(model, psu_op = 1, socio_level = temp_socio_level)

g2 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 社会志向,  
                             group = 社会志向, fill = 社会志向)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と野党派間での投票確率の差") +
  ggtitle("野党投票(社会志向)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()



#----与党派と無党派間での与党投票の場合
  model <- zelig(vote_rul ~ socio_level + educ + employ + interest + age + gender + 
                   psu_indep + ego + income, 
                     data = filtered_df, model = "logit", cite = "FALSE")
  x.notrul <- setx(model, psu_indep = 0, socio_level = temp_socio_level)
  x.rul <- setx(model, psu_indep = 1, socio_level = temp_socio_level)

g3 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 社会志向,  
                             group = 社会志向, fill = 社会志向)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("与党派と無党派での投票確率の差") +
  ggtitle("与党投票(社会志向)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()


#----野党派と無党派間での野党投票の場合
model <- zelig(vote_op ~ socio_level + educ + employ + interest + age + gender + 
                 psu_indep + ego + income, 
                     data = filtered_df, model = "logit", cite = "FALSE")
x.notrul <- setx(model, psu_indep = 0, socio_level = temp_socio_level)
x.rul <- setx(model, psu_indep = 1, socio_level = temp_socio_level)

g4 <- ggplot(data=results_df, aes(y=値, x=年, ymin=下側, ymax=上側, linetype = 社会志向,  
                             group = 社会志向, fill = 社会志向)) +
  geom_hline(yintercept=0, color="black", size=0.5) +
  geom_errorbar(size=.2, width=.1, linetype=1, color="gray60") +
  geom_point(size=1.5, color="black", fill="black", alpha=.85) +
  geom_smooth( se=T, col="black", size=1, fullrange = TRUE, alpha = .15) +
  scale_x_continuous(limits=c(1980,2020), breaks=c(1980,1990,2000,2010,2015,2020)) +
  scale_y_continuous(limits=c(-.325,.612), breaks=c(-.3,-.2,-.1,0,.1,.2,.3,.4,.5,.6)) +
  coord_cartesian(ylim=c(-.3,.6))+
  xlab("") + ylab("野党派と無党派での投票確率の差") +
  ggtitle("野党投票(社会志向)") +
  theme(axis.title.x = element_blank(), 
        axis.title.y = element_blank(), 
        axis.text.y = element_blank(), 
        axis.ticks.y = element_blank(),legend.position = c(0.2, 0.2))+theme_bw()


grid.arrange(g1, g2, g3, g4, ncol = 2)

第8章: 経済情報をどのように受け取っているのか?─実験データの分析(1)

実験8-1・データの前処理

#------------------
# データの読み込み
#------------------
dat8_exp1<-read.csv("econ_factor.csv", fileEncoding = "SJIS")

#------------------
# 変数の設定
#------------------

#----処置変数:グループ設定(1)
#失業率・肯定
group_unemp_positive<-Q4.1
group_unemp_positive[Q4.1==1]<-"失業・肯定"


#失業率・否定
group_unemp_negative<-Q5.1
group_unemp_negative[Q5.1==1]<-"失業・否定"

#物価・肯定
group_price_positive<-Q6.1
group_price_positive[Q6.1>0]<-"物価・肯定"


#物価・否定
group_price_negative<-Q7.1
group_price_negative[Q7.1>0]<-"物価・否定"

#株価・肯定
group_stock_positive<-Q8.1
group_stock_positive[Q8.1>0]<-"株価・肯定"


#株価・否定
group_stock_negative<-Q9.1
group_stock_negative[Q9.1>0]<-"株価・否定"



#成長・肯定
group_growth_positive<-Q10.1
group_growth_positive[Q10.1>0]<-"成長・肯定"


#成長・否定
group_growth_negative<-Q11.1
group_growth_negative[Q11.1>0]<-"成長・否定"

#統制群
group_control<-Q12.1
group_control[Q12.1>0]<-"統制群"


#統合
dat8_exp1$group<-coalesce(group_unemp_positive,group_unemp_negative, 
                group_price_positive,group_price_negative,
                group_stock_positive,group_stock_negative,
                group_growth_positive,group_growth_negative,
                group_control)


#----処置変数:グループ設定(2)
#失業率・肯定
dat8_exp1 <-  dat8_exp1 %>%
  mutate(
    # 失業率・肯定
    group_unemp_positiven = if_else(group_unemp_positiven == 1, 1, group_unemp_positiven),
    group_unemp_positiven = replace(group_unemp_positiven, is.na(group_unemp_positiven), 0),
    
    # 失業率・否定
    group_unemp_negativen = if_else(group_unemp_negativen == 1, 1, group_unemp_negativen),
    group_unemp_negativen = replace(group_unemp_negativen, is.na(group_unemp_negativen), 0),
    
    # 物価・肯定
    group_price_positiven = if_else(group_price_positiven > 0, 1, group_price_positiven),
    group_price_positiven = replace(group_price_positiven, is.na(group_price_positiven), 0),
    
    # 物価・否定
    group_price_negativen = if_else(group_price_negativen > 0, 1, group_price_negativen),
    group_price_negativen = replace(group_price_negativen, is.na(group_price_negativen), 0),
    
    # 株価・肯定
    group_stock_positiven = if_else(group_stock_positiven > 0, 1, group_stock_positiven),
    group_stock_positiven = replace(group_stock_positiven, is.na(group_stock_positiven), 0),
    
    # 株価・否定
    group_stock_negativen = if_else(group_stock_negativen > 0, 1, group_stock_negativen),
    group_stock_negativen = replace(group_stock_negativen, is.na(group_stock_negativen), 0),
    
    # 成長・肯定
    group_growth_positiven = if_else(group_growth_positiven > 0, 1, group_growth_positiven),
    group_growth_positiven = replace(group_growth_positiven, is.na(group_growth_positiven), 0),
    
    # 成長・否定
    group_growth_negativen = if_else(group_growth_negativen > 0, 1, group_growth_negativen),
    group_growth_negativen = replace(group_growth_negativen, is.na(group_growth_negativen), 0),
    
    # 統制群
    group_controln = if_else(group_controln > 0, 1, group_controln),
    group_controln = replace(group_controln, is.na(group_controln), 0)
  )


#---- 政党支持変数
dat8_exp1 <- dat8_exp1 %>%
  mutate(
    # 政党支持(文字列)
    psu = case_when(
      Q2.4 %in% c(1, 3) ~ "与党派",
      Q2.4 %in% c(2, 4, 5, 6, 7, 8, 9) ~ "野党派",
      Q2.4 == 10 ~ "無党派",
      Q2.4 %in% c(11, 12) ~ NA_character_,
      TRUE ~ NA_character_
    ),
    # 与党支持ダミー
    psu_rul = case_when(
      Q2.4 %in% c(1, 3) ~ 1,
      Q2.4 %in% c(2, 4, 5, 6, 7, 8, 9, 10) ~ 0,
      Q2.4 %in% c(11, 12) ~ NA_real_,
      TRUE ~ NA_real_
    ),
    # 野党支持ダミー
    psu_op = case_when(
      Q2.4 %in% c(1, 3) ~ 0,
      Q2.4 %in% c(2, 4, 5, 6, 7, 8, 9) ~ 1,
      Q2.4 == 10 ~ 0,
      Q2.4 %in% c(11, 12) ~ NA_real_,
      TRUE ~ NA_real_
    ),
    # 無党派ダミー
    psu_indep = case_when(
      Q2.4 %in% c(1, 3) ~ 0,
      Q2.4 %in% c(2, 4, 5, 6, 7, 8, 9) ~ 0,
      Q2.4 == 10 ~ 1,
      Q2.4 %in% c(11, 12) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )



#---- 内閣支持変数
cabap <- dat8_exp1$Q3.3

cabap[dat8_exp1$Q3.3 == 1] <- 5
cabap[dat8_exp1$Q3.3 == 2] <- 4
cabap[dat8_exp1$Q3.3 == 4] <- 2
cabap[dat8_exp1$Q3.3 == 5] <- 1
cabap[dat8_exp1$Q3.3 %in% c(6,7)] <- NA

dat8_exp1$cabap <- cabap

cabap_names <- paste0("cabap", 1:9)            
Q_values    <- paste0("Q", 4:12, ".4")        

for(i in seq_along(cabap_names)) {
  temp <- dat8_exp1[[ Q_values[i] ]]         
  
  temp[dat8_exp1[[ Q_values[i] ]] == 1] <- 5
  temp[dat8_exp1[[ Q_values[i] ]] == 2] <- 4
  temp[dat8_exp1[[ Q_values[i] ]] == 4] <- 2
  temp[dat8_exp1[[ Q_values[i] ]] == 5] <- 1
  temp[dat8_exp1[[ Q_values[i] ]] %in% c(6, 7)] <- NA
  
  dat8_exp1[[ cabap_names[i] ]] <- temp
}


dat8_exp1$cabapps <- coalesce(
  dat8_exp1$cabap1, dat8_exp1$cabap2, dat8_exp1$cabap3,
  dat8_exp1$cabap4, dat8_exp1$cabap5, dat8_exp1$cabap6,
  dat8_exp1$cabap7, dat8_exp1$cabap8, dat8_exp1$cabap9
)


cabapch1 <- dat8_exp1$cabapps - dat8_exp1$cabap

cabapch <- cabapch1
cabapch[cabapch1 < 0] <- -1
cabapch[cabapch1 > 0] <-  1
cabapch[cabapch1 == 0] <- 0

dat8_exp1$cabapch <- cabapch


#---- 内閣支持変化・順序変数
cabapch <- cabapps - cabap
cabapch_or <- cabapch
cabapch_or[cabapch > 0] <- 1
cabapch_or[cabapch == 0] <- 0
cabapch_or[cabapch < 0] <- -1


#---- 処置前経済評価変数

#国レベルの経済評価
naecon <- Q3.1_1
naecon[Q3.1_1 == 1] <- 5
naecon[Q3.1_1 == 2] <- 4
naecon[Q3.1_1 == 4] <- 2
naecon[Q3.1_1 == 5] <- 1
naecon[Q3.1_1 == 6 | Q3.1_1 ==7] <- NA

#景気評価
busiecon <- Q3.1_2
busiecon[Q3.1_2 == 1] <- 5
busiecon[Q3.1_2 == 2] <- 4
busiecon[Q3.1_2 == 4] <- 2
busiecon[Q3.1_2 == 5] <- 1
busiecon[Q3.1_2 == 6 | Q3.1_2 ==7] <- NA

#暮らし向き評価
livecon <- Q3.1_3
livecon[Q3.1_3 == 1] <- 5
livecon[Q3.1_3 == 2] <- 4
livecon[Q3.1_3 == 4] <- 2
livecon[Q3.1_3 == 5] <- 1
livecon[Q3.1_3 == 6 | Q3.1_3 ==7] <- NA


#---- 処置後経済評価変数

#処置後・国レベルの経済評価

naecon_names <- paste0("naecon", 1:9)

Q_values <- paste0("Q", 4:12, ".2_1")

for(i in 1:9) {
  assign(naecon_names[i], get(Q_values[i]))
  temp <- get(cabap_names[i])
  temp[get(Q_values[i]) == 1] <- 5
  temp[get(Q_values[i]) == 2] <- 4
  temp[get(Q_values[i]) == 4] <- 2
  temp[get(Q_values[i]) == 5] <- 1
  temp[get(Q_values[i]) %in% c(6,7)] <- NA
  assign(naecon_names[i], temp)
}

naeconps <- coalesce(naecon1, naecon2, naecon3, naecon4, naecon5, naecon6, naecon7, naecon8, naecon9)


#処置後・景気評価
busiecon_names <- paste0("busiecon", 1:9)
Q_values <- paste0("Q", 4:12, ".2_2")
for(i in 1:9) {
  assign(busiecon_names[i], get(Q_values[i]))
  temp <- get(cabap_names[i])
  temp[get(Q_values[i]) == 1] <- 5
  temp[get(Q_values[i]) == 2] <- 4
  temp[get(Q_values[i]) == 4] <- 2
  temp[get(Q_values[i]) == 5] <- 1
  temp[get(Q_values[i]) %in% c(6,7)] <- NA
  assign(busiecon_names[i], temp)
}

busieconps <- coalesce(busiecon1, busiecon2, busiecon3, busiecon4, busiecon5, busiecon6, busiecon7, busiecon8, busiecon9)


#処置後・暮らし向き評価
livecon_names <- paste0("livecon", 1:9)
Q_values <- paste0("Q", 4:12, ".2_3")
for(i in 1:9) {
  assign(livecon_names[i], get(Q_values[i]))
  temp <- get(cabap_names[i])
  temp[get(Q_values[i]) == 1] <- 5
  temp[get(Q_values[i]) == 2] <- 4
  temp[get(Q_values[i]) == 4] <- 2
  temp[get(Q_values[i]) == 5] <- 1
  temp[get(Q_values[i]) %in% c(6,7)] <- NA
  assign(livecon_names[i], temp)
}

liveconps <- coalesce(livecon1, livecon2, livecon3, livecon4, livecon5, livecon6, livecon7, livecon8, livecon9)


#---- 経済評価変化・順序変数
naeconch <- naeconps - naecon
naeconch_or <- naeconch
naeconch_or[naeconch > 0] <- 1
naeconch_or[naeconch == 0] <- 0
naeconch_or[naeconch < 0] <- -1

liveconch <- liveconps - livecon
liveconch_or <- liveconch
liveconch_or[liveconch > 0] <- 1
liveconch_or[liveconch == 0] <- 0
liveconch_or[liveconch < 0] <- -1


busieconch <- busieconps - busiecon
busieconch_or <- busieconch
busieconch_or[busieconch > 0] <- 1
busieconch_or[busieconch == 0] <- 0
busieconch_or[busieconch < 0] <- -1


#---- 共変量
#年齢
age<-Q2.2

#所得
income<-Q3.2_1

#所得グループ
income_group <- income
income_group[income < 300] <- 1
income_group[income >= 300 & income < 489] <- 2
income_group[income >= 489 & income < 761] <- 3
income_group[income >= 761] <- 4

#性別
gender<-Q2.1
gender[Q2.1==1]<-1
gender[Q2.1==2]<-0  
gender[Q2.1==3|Q2.1==4]<-NA

#教育歴
education <- Q2.4
education[Q2.4 == 4 |Q2.4 ==5] <- 4
education[Q2.4 == 6 | Q2.4 == 7] <- NA

本文の補足分析と各図表のコード

図8-4:【実験8-1】処置ごとでの平均値の差(事前質問から事後質問への変化)

#----------------
# 関数の読み込み
#----------------
source("plot8_4.R")

#--------------
# データの設定
#--------------
df <- dat8_exp1 %>% 
    mutate(
    group = factor(group, levels = c("統制群", "失業・肯定", "物価・肯定", "成長・肯定",
                                     "株価・肯定", "失業・否定", "物価・否定", 
                                     "成長・否定","株価・否定")),
    color_assign = case_when(
      group == "統制群" ~ "darkgrey",
      str_detect(group, "否定") ~ "lightgrey",
      TRUE ~ "grey"
    ) %>%
   na.omit()
  )


my_comparisons <- list(
  c("統制群", "失業・肯定"),
  c("統制群", "物価・肯定"),
  c("統制群", "成長・肯定"),
  c("統制群", "株価・肯定"),
  c("統制群", "失業・否定"),
  c("統制群", "物価・否定"),
  c("統制群", "成長・否定"),
  c("統制群", "株価・否定")
)

titles <- list(
  naeconch   = "国レベルの経済評価",
  busieconch = "景気評価",
  liveconch  = "暮らし向き評価",
  cabapch    = "内閣支持"
)


#----------------------
# プロットの作成と表示
#----------------------
p_list <- names(titles) %>% 
  set_names() %>% 
  map(~ plot8_4(df, .x, titles, my_comparisons))

grid.arrange(grobs = p_list, ncol = 2)

図8-5:【実験8-1】処置と党派性ごとでの経済評価変化値の平均値の差(国レベルでの経済評価)

図8-6:【実験8-1】処置と党派性ごとでの経済評価変化値の平均値の差(景気評価)

図8-7:【実験8-1】処置と党派性ごとでの経済評価変化値の平均値の差(暮らし向き評価)

景気評価はbusieconch、暮らし向き評価はliveconchにそれぞれ置き換えることで、同様の図を作成できる。

#--------------
# データの設定
#--------------
dat_exp1_5 <- na.omit(data.frame(group, psu, naeconch))

dat_exp1_5 <- dat_exp1_5[dat_exp1_5$psu != '無党派',]
dat_exp1_5$psu[dat_exp1_5$psu == '与党派'] <- 'R'
dat_exp1_5$psu[dat_exp1_5$psu == '野党派'] <- 'O'

#----------------
# プロットの作成
#----------------
#---- ベースとなるjitterのプロットの作成
set.seed(123)  
dat_exp1_5$naeconch_jittered <- jitter(dat_exp1_5$naeconch, amount=0.1)

h <- ggplot(dat_exp1_5, aes(x=group, y=naeconch)) +
  geom_text(data = subset(dat_exp1_5, psu == "R"), aes(label = psu, color = "R"),
            position = position_jitter(width = 0.2, height = 0.2), show.legend = FALSE) +
  geom_text(data = subset(dat_exp1_5, psu == "O"), aes(label = psu, color = "O"),
            position = position_jitter(width = 0.2, height = 0.2), show.legend = FALSE) +
  scale_color_manual(values = c("与党派"="black", "野党派"="black", "無党派"="black")) +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  xlab("処置") +
  ylab("国レヴェルの経済評価")+guides(color = FALSE) 

#---- 平均値の差に関する重ね書き
dat_exp1_5s <- na.omit(data.frame(naeconch, group, psu))
dat_exp1_5s <- summarySE(dat_exp1_5s, measurevar="naeconch", groupvars=c("group", "psu"))
dat_exp1_5s<- transform(dat_exp1_5s,psu=factor(psu,
                                levels=c("与党派","野党派","無党派")))
dat_exp1_5s<- transform(dat_exp1_5s,group=factor(group,
                                        levels=c("統制群", "失業・肯定", "物価・肯定", "成長・肯定",
                                                 "株価・肯定" ,"失業・否定",
                                                 "物価・否定","株価・否定","成長・否定")))
 
plot8_5 <- h + 
  geom_linerange(data = dat_exp1_5s, aes(ymin = naeconch - ci, ymax = naeconch + ci, color = psu, linetype = psu),
                 size = 1, position = position_dodge(0.7)) +
  geom_point(data = dat_exp1_5s, aes(x = group, y = naeconch, color = psu, shape = psu), 
             position = position_dodge(0.7), size = 3) +
  ylim(-2.5, 2.5) +
  scale_shape_manual(values = c("与党派" = 16, "野党派" = 17, "無党派" = 18))+ 
  guides(color = FALSE) +
  labs(shape = "党派性", linetype="党派性")+
  geom_hline(yintercept = 0, linetype = "dashed", color = "black", show.legend = FALSE) 

【補足】推定方法の説明

実験8-1のデータをどのように分析するか?

本分析では、被験者が認識する「国レベルの経済評価」を結果変数として、順序ロジスティック回帰モデを用いた推定を行う。具体的には、党派性変数、および各種経済領域についての肯定的情報と否定的情報の変数を組み合わせ、その交互作用の効果が各種の経済評価に与える影響を推定する。経済評価が良化(+1)、変化なし(0)、悪化(-1)と推移することを、各結果変数では指標化している。このかくっけか変数を従属変数として、本分析の順序ロジスティック回帰モデルは、次のように設定する;

\[\begin{eqnarray} logit[p(Y\leq c|X)]=\alpha_c-(\beta_1x_{partisanship}+\beta_2x_{treatment}+\beta_3(x_{partisanship}\times x_{treatment})\\ +\gamma_{1}x_{age}+\gamma_{2}x_{gender}+\gamma_3x_{income}\\ +\gamma_4x_{education}) \end{eqnarray}\]

ここで、党派性変数、経済情報変数、それらの交差項の係数はそれぞれ\(\beta_1\), \(\beta_2\), \(\beta_3\)であり、\(c\)は従属変数のカテゴリ番号、\(\alpha_c\)は各カテゴリの閾値を表す。各\(\gamma\)はそれぞれの共変量の係数である。この設定に基づく推定をベースとして、シミュレーションを行う。

図8-8:【実験8-1】処置に対する反応の党派性差異(国レベルの経済評価)

図8-9:【実験8-1】処置に対する反応の党派性差異(景気評価)

図8-10:【実験8-1】処置に対する反応の党派性差異(暮らし向き評価)

図8-11:【実験8-1】処置に対する反応の党派性差異(内閣支持)

景気評価はbusieconch、暮らし向き評価はliveconch、内閣支持はcabapchにそれぞれ置き換えることで、同様の図を作成できる。

#--------------
# データの設定
#--------------
dat8_exp1_8 <- na.omit(data.frame(cabapps, naeconps, liveconps,busieconps, group_growth_negativen,
                             group_growth_positiven, group_stock_negativen, group_stock_positiven, 
                             group_price_negativen, group_price_positiven, group_unemp_negativen,
                             group_unemp_positiven, group_controln, gender, age, education, income, 
                             psu_rul, psu_op, psu_indep,naeconch_or,busieconch_or,liveconch_or,cabapch,
                             cabapch_or))

#-----------------------------
# シミュレーションの設定と実施
#-----------------------------
psu_vars <- c("psu_rul", "psu_op", "psu_indep")
economic_factors <- c("unemp", "growth", "stock", "price")
evaluation <- c("positiven", "negativen")

results1 <- list()
results2 <- list()

for (psu_var in psu_vars) {
  for (economic_factor in economic_factors) {
    for (eval in evaluation) {
      group_var <- paste0("group_", economic_factor, "_", eval)
      
      zelig_formula <- as.formula(paste0("as.factor(naeconch_or) ~ ", psu_var, " + ", group_var, 
                                         " + age + gender + income + education + ", 
                                         group_var, ":", psu_var))
      
      zpar <- zelig(zelig_formula, data = dat8_exp1_8, model = "ologit", cite = "FALSE")
      
      
      x.notrul_args <- list(zpar)
      x.notrul_args[[psu_var]] <- 1
      x.notrul_args[[group_var]] <- 0
      
      x.rul_args <- list(zpar)
      x.rul_args[[psu_var]] <- 1
      x.rul_args[[group_var]] <- 1
      
      x.notrul <- do.call(setx, x.notrul_args)
      x.rul <- do.call(setx, x.rul_args)
      
      s.out <- sim(zpar, x = x.notrul, x1 = x.rul)
      
      sim1 <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]][,1]) 
      sim2 <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]][,3]) 
      
      results1[[paste0(psu_var, "_fd_", group_var)]] <- quantile(sim1[,1], c(0.5, .025, .975))
      results2[[paste0(psu_var, "_fd_", group_var)]] <- quantile(sim2[,1], c(0.5, .025, .975))
    }
  }
}

#----------------
# 分析結果の成形
#----------------

#---- 良化方向の変化
results_df1 <- do.call(rbind, results1)

df_econf1 <- data.frame(cbind(results_df1, c("失業・肯定","失業・否定","成長・肯定","成長・否定",
                               "株価・肯定","株価・否定","物価・肯定","物価・否定",
                               "失業・肯定","失業・否定","成長・肯定","成長・否定",
                               "株価・肯定","株価・否定","物価・肯定","物価・否定",
                               "失業・肯定","失業・否定","成長・肯定","成長・否定",
                               "株価・肯定","株価・否定","物価・肯定","物価・否定"),
                            c("与党派","与党派","与党派","与党派","与党派","与党派",
                              "与党派","与党派","野党派","野党派","野党派","野党派",
                              "野党派","野党派","野党派","野党派","無党派","無党派",
                              "無党派","無党派","無党派","無党派","無党派","無党派"),
                            "悪い"))
colnames(df_econf1) <- c("coef", "low", "up", "経済情報", "党派性","回答")
df_econf1$coef <- as.numeric(df_econf1$coef)
df_econf1$up <- as.numeric(df_econf1$up)
df_econf1$low <- as.numeric(df_econf1$low)


#---- 悪化方向の変化
results_df2 <- do.call(rbind, results2)

df_econf2 <- data.frame(cbind(results_df2, c("失業・肯定","失業・否定","成長・肯定","成長・否定",
                                             "株価・肯定","株価・否定","物価・肯定","物価・否定",
                                             "失業・肯定","失業・否定","成長・肯定","成長・否定",
                                             "株価・肯定","株価・否定","物価・肯定","物価・否定",
                                             "失業・肯定","失業・否定","成長・肯定","成長・否定",
                                             "株価・肯定","株価・否定","物価・肯定","物価・否定"),
                              c("与党派","与党派","与党派","与党派","与党派","与党派",
                                "与党派","与党派","野党派","野党派","野党派","野党派",
                                "野党派","野党派","野党派","野党派","無党派","無党派",
                                "無党派","無党派","無党派","無党派","無党派","無党派"),
                              "良い"))
colnames(df_econf2) <- c("coef", "low", "up", "経済情報", "党派性","回答")
df_econf2$coef <- as.numeric(df_econf2$coef)
df_econf2$up <- as.numeric(df_econf2$up)
df_econf2$low <- as.numeric(df_econf2$low)


#---- 両方向変化に関するデータフレームの統合など
df_econf <- rbind(df_econf1, df_econf2)

df_econf <- df_econf %>%
  mutate(党派性 = factor(党派性, levels = c("与党派", "野党派", "無党派")))

df_econf <- df_econf %>%
  mutate(経済情報 = factor(経済情報, levels = c("失業・肯定", "物価・肯定",
                                      "成長・肯定", "株価・肯定",
                                      "失業・否定", "物価・否定",
                                      "成長・否定", "株価・否定")))


#----------------
# プロットの作成
#----------------
df_econf <- df_econf %>%
  mutate(highlight = ifelse((low > 0 & up > 0) | (low < 0 & up < 0), TRUE, FALSE))

df_good <- subset(df_econf, 回答 == "良い")
df_bad <- subset(df_econf, 回答 == "悪い")

dodge_width <- 0.2

#---- 良化方向の変化
h1 <- ggplot(df_good, aes(x = 経済情報, y = coef, ymin = low, ymax = up, group = 党派性)) +
  geom_rect(
    data = subset(df_good, highlight == TRUE & 党派性 == "与党派"),
    aes(
      xmin = as.numeric(as.factor(経済情報)) - 0.15 ,  
      xmax = as.numeric(as.factor(経済情報)) - 0.05,  
      ymin = low, ymax = up
    ), 
    fill = "grey90", alpha = 0.5, inherit.aes = FALSE
  ) +
  geom_rect(
    data = subset(df_good, highlight == TRUE & 党派性 == "野党派"),
    aes(
      xmin = as.numeric(as.factor(経済情報)) - 0.03,  
      xmax = as.numeric(as.factor(経済情報)) + 0.03,  
      ymin = low, ymax = up
    ), 
    fill = "grey90", alpha = 0.5, inherit.aes = FALSE
  ) +
  geom_rect(
    data = subset(df_good, highlight == TRUE & 党派性 == "無党派"),
    aes(
      xmin = as.numeric(as.factor(経済情報)) + 0.05,  
      xmax = as.numeric(as.factor(経済情報)) + 0.15,  
      ymin = low, ymax = up
    ), 
    fill = "grey90", alpha = 0.5, inherit.aes = FALSE
  ) +
  geom_errorbar(aes(linetype = 党派性), width = 0.1, position = position_dodge(0.3)) + 
  geom_point(aes(shape = 党派性), position = position_dodge(0.3), alpha = 0.6) +
  geom_hline(yintercept = 0, linetype="dashed", color = "black") +
  geom_text(
    data = subset(df_good, highlight == TRUE & 党派性 == "与党派"), 
    aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
    nudge_x = -0.05,  
    nudge_y = 0.05,   
    size = 3.5, hjust = 1
  ) +
  geom_text(
    data = subset(df_good, highlight == TRUE & 党派性 == "無党派"), 
    aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
    nudge_x = 0.05,   
    nudge_y = 0.05,   
    size = 3.5, hjust = 0
  ) +
  labs(x = "経済情報", y = "選択確率の差異(情報=1と情報=0の差)", title = "国レヴェルの経済評価(良い)") +
  theme_bw() +
  theme(legend.position = "right")


#---- 悪化方向の変化
h2 <- ggplot(df_bad, aes(x = 経済情報, y = coef, ymin = low, ymax = up, group = 党派性)) +
  geom_rect(
    data = subset(df_bad, highlight == TRUE & 党派性 == "与党派"),
    aes(
      xmin = as.numeric(as.factor(経済情報)) - 0.15 ,  
      xmax = as.numeric(as.factor(経済情報)) - 0.05,  
      ymin = low, ymax = up
    ), 
    fill = "grey90", alpha = 0.5, inherit.aes = FALSE
  ) +
  geom_rect(
    data = subset(df_bad, highlight == TRUE & 党派性 == "野党派"),
    aes(
      xmin = as.numeric(as.factor(経済情報)) - 0.03,  
      xmax = as.numeric(as.factor(経済情報)) + 0.03,  
      ymin = low, ymax = up
    ), 
    fill = "grey90", alpha = 0.5, inherit.aes = FALSE
  ) +
  geom_rect(
    data = subset(df_bad, highlight == TRUE & 党派性 == "無党派"),
    aes(
      xmin = as.numeric(as.factor(経済情報)) + 0.05,  
      xmax = as.numeric(as.factor(経済情報)) + 0.15,  
      ymin = low, ymax = up
    ), 
    fill = "grey90", alpha = 0.5, inherit.aes = FALSE
  ) +
  geom_errorbar(aes(linetype = 党派性), width = 0.1, position = position_dodge(0.3)) +  
  geom_point(aes(shape = 党派性), position = position_dodge(0.3), alpha = 0.6) +
  geom_hline(yintercept = 0, linetype="dashed", color = "black") +
  geom_text(
    data = subset(df_bad, highlight == TRUE & 党派性 == "与党派"), 
    aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
    nudge_x = -0.05, 
    nudge_y = 0.05,  
    size = 3.5, hjust = 1
  ) +
  geom_text(
    data = subset(df_bad, highlight == TRUE & 党派性 == "無党派"), 
    aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
    nudge_x = 0.05, 
    nudge_y = 0.05,   
    size = 3.5, hjust = 0
  ) +
  labs(x = "経済情報", y = "選択確率の差異(情報=1と情報=0の差)", title = "国レヴェルの経済評価(悪い)") +
  theme_bw() +
  theme(legend.position = "right")

plot8_8 <- grid.arrange(h1, h2, ncol = 1)

【補足】順序ロジスティック回帰推定の結果

以下では、シミュレーションの基盤となる順序ロジット推定の結果を報告する。表内のアスタリスク(*)は、5%水準で統計的に有意であることを表す。

#--------------
# データの設定
#--------------
dat8_exp1_8 <- na.omit(data.frame(cabapps, naeconps, liveconps,busieconps, group_growth_negativen,
                             group_growth_positiven, group_stock_negativen, group_stock_positiven, 
                             group_price_negativen, group_price_positiven, group_unemp_negativen,
                             group_unemp_positiven, group_controln, gender, age, education, income, 
                             psu_rul, psu_op, psu_indep,naeconch_or,busieconch_or,liveconch_or,cabapch,
                             cabapch_or))

#----------------
# 関数の読み込み
#----------------
source("ologit8_exp1.R")


#--------------------------
# 従属変数と独立変数の設定
#--------------------------
dv_vars <- c("naeconch_or", "busieconch_or", "liveconch_or", "cabapch")
dv_labels <- c("国レベル", "1年前比較", "景気評価", "暮らし向き評価")

iv_vars <- c("psu_rul", "psu_op",
             "group_growth_positiven", "group_growth_negativen",
             "group_stock_positiven", "group_stock_negativen",
             "group_price_positiven", "group_price_negativen",
             "group_unemp_positiven", "group_unemp_negativen",
             "age", "gender", "income", "education")

indep_order <- c("psu_rul", "psu_op",
                 "group_growth_positiven", "group_growth_negativen",
                 "group_stock_positiven", "group_stock_negativen",
                 "group_price_positiven", "group_price_negativen",
                 "group_unemp_positiven", "group_unemp_negativen",
                 "age", "gender", "income", "education")
indep_labels <- c("与党支持", "野党支持",
                  "成長(+)", "成長(-)",
                  "株価(+)", "株価(-)",
                  "物価(+)", "物価(-)",
                  "雇用(+)", "雇用(-)",
                  "年齢", "性別", "所得", "教育歴")

#------------------------
# 順序ロジット推定の実行
#------------------------
dv_results_list <- lapply(dv_vars, ologit8_exp1)
names(dv_results_list) <- dv_vars

final_df <- data.frame(独立変数 = dv_results_list[[1]]$Variable, stringsAsFactors = FALSE)
for(i in 1:length(dv_vars)) {
  df_i <- dv_results_list[[dv_vars[i]]]
  colnames(df_i)[2:3] <- c(paste0(dv_labels[i], "_係数"), paste0(dv_labels[i], "_オッズ比"))
  final_df <- cbind(final_df, df_i[,2:3])
}

tb_ol <- kable(final_df, format = "html", align = "c", row.names = FALSE) %>%
  kable_styling(full_width = FALSE)

各従属変数の順序ロジット推定結果

独立変数 国レベル_係数 国レベル_オッズ比 1年前比較_係数 1年前比較_オッズ比 景気評価_係数 景気評価_オッズ比 暮らし向き評価_係数 暮らし向き評価_オッズ比
与党支持 0.618* (0.091) 1.855* (1.552, 2.217) 0.514* (0.092) 1.672* (1.396, 2.002) 1.216* (0.093) 3.374* (2.812, 4.048) -0.677* (0.317) 0.508* (0.273, 0.946)
野党支持 0.041 (0.083) 1.042 (0.885, 1.226) -0.055 (0.083) 0.946 (0.804, 1.114) -0.043 (0.082) 0.958 (0.816, 1.125) -0.404 (0.233) 0.668 (0.423, 1.054)
成長(+) 0.062 (0.139) 1.064 (0.810, 1.397) 0.165 (0.141) 1.179 (0.895, 1.555) -0.079 (0.137) 0.924 (0.706, 1.209) 0.282 (0.272) 1.326 (0.778, 2.259)
成長(-) -0.533* (0.138) 0.587* (0.448, 0.769) -0.329* (0.139) 0.720* (0.548, 0.945) -0.290* (0.138) 0.748* (0.571, 0.981) 0.145 (0.273) 1.156 (0.677, 1.974)
株価(+) 0.212 (0.139) 1.236 (0.941, 1.623) 0.255 (0.140) 1.290 (0.981, 1.698) -0.072 (0.136) 0.931 (0.713, 1.215) 0.116 (0.269) 1.123 (0.663, 1.903)
株価(-) -0.300* (0.139) 0.741* (0.564, 0.973) -0.356* (0.139) 0.700* (0.533, 0.920) 0.016 (0.138) 1.016 (0.775, 1.332) -0.753* (0.245) 0.471* (0.291, 0.761)
物価(+) 0.240 (0.138) 1.271 (0.970, 1.666) 0.196 (0.140) 1.217 (0.925, 1.601) 0.143 (0.137) 1.154 (0.882, 1.509) 0.192 (0.271) 1.212 (0.712, 2.061)
物価(-) -0.445* (0.137) 0.641* (0.490, 0.838) -0.371* (0.138) 0.690* (0.527, 0.904) -0.122 (0.137) 0.885 (0.677, 1.158) -0.325 (0.258) 0.723 (0.436, 1.198)
雇用(+) 0.079 (0.139) 1.082 (0.824, 1.421) 0.204 (0.140) 1.226 (0.932, 1.613) 0.013 (0.137) 1.013 (0.775, 1.325) 0.232 (0.272) 1.261 (0.740, 2.149)
雇用(-) -0.434* (0.136) 0.648* (0.496, 0.846) -0.329* (0.137) 0.720* (0.550, 0.941) -0.020 (0.135) 0.980 (0.752, 1.277) -0.626* (0.246) 0.535* (0.330, 0.866)
年齢 -0.004 (0.003) 0.996 (0.990, 1.002) -0.006* (0.003) 0.994* (0.988, 1.000) 0.008* (0.003) 1.008* (1.002, 1.014) 0.004 (0.005) 1.004 (0.994, 1.014)
性別 0.290* (0.071) 1.336* (1.163, 1.536) 0.214* (0.072) 1.239* (1.076, 1.426) 0.187* (0.070) 1.206* (1.051, 1.383) -0.260* (0.130) 0.771* (0.598, 0.995)
所得 -0.000 (0.000) 1.000 (1.000, 1.000) -0.000 (0.000) 1.000 (1.000, 1.000) -0.000* (0.000) 1.000* (1.000, 1.000) 0.000* (0.000) 1.000* (1.000, 1.000)
教育歴 -0.012 (0.010) 0.988 (0.969, 1.008) -0.041* (0.010) 0.960* (0.941, 0.979) -0.010 (0.010) 0.990 (0.971, 1.010) -0.069* (0.035) 0.933* (0.871, 1.000)
モデルの要約 n=4017, R2=0.023, LogLR=157.634 n=4017, R2=0.023, LogLR=157.634 n=4017, R2=0.025, LogLR=167.884 n=4017, R2=0.025, LogLR=167.884 n=4017, R2=0.041, LogLR=284.676 n=4017, R2=0.041, LogLR=284.676 n=4017, R2=0.018, LogLR=47.722 n=4017, R2=0.018, LogLR=47.722

【実験8-1】データの検討:バランス・チェックと加重付与による追試)

バランス・チェック

バランス・チェックによれば、群間で主要な変数間の分布に統計的な有意差がなく、群間の単位同質性が著しく侵害されていることを示す結果とはなっていない。しかし、群間で完全な均質性が保たれているわけではないことから、一般的な傾向スコア、エントロピー・バランシングによって、データを重みづけした推定結果を、参考として示す。

#-------------------------
#バランス・チェックの実行
#-------------------------
dat8_exp1_bc <- na.omit(data.frame(group, age, gender, education, income_group, psu_rul))
tb_bc1 <- sumtable(dat8_exp1_bc, group = "group", group.test = TRUE, title = "")

実験8-1のバランス・チェックの結果

Table 1:
group
株価・肯定
株価・否定
失業・肯定
失業・否定
成長・肯定
成長・否定
統制群
物価・肯定
物価・否定
Variable N Mean SD N Mean SD N Mean SD N Mean SD N Mean SD N Mean SD N Mean SD N Mean SD N Mean SD Test
age 469 34 12 463 34 12 462 33 12 482 35 12 469 34 12 458 34 12 469 34 12 465 33 12 459 34 12 F=1.207
gender 469 0.3 0.46 463 0.36 0.48 462 0.35 0.48 482 0.35 0.48 469 0.39 0.49 458 0.31 0.46 469 0.37 0.48 465 0.34 0.47 459 0.34 0.47 F=1.494
education 469 6.8 3.9 463 6.7 3.8 462 7.1 3.9 482 6.7 3.9 469 7.1 3.8 458 6.8 3.9 469 6.8 4 465 6.8 3.9 459 6.6 3.9 F=0.816
income_group 469 2.5 1.1 463 2.5 1.1 462 2.6 1.1 482 2.5 1.1 469 2.5 1.1 458 2.5 1.1 469 2.5 1.1 465 2.5 1.1 459 2.6 1.1 F=0.404
psu_rul 469 0.22 0.41 463 0.21 0.41 462 0.23 0.42 482 0.24 0.43 469 0.2 0.4 458 0.25 0.43 469 0.24 0.43 465 0.25 0.43 459 0.25 0.43 F=0.884
Statistical significance markers: * p<0.1; ** p<0.05; *** p<0.01

傾向スコアによるデータへの重みづけ

#--------------------------
# 加重算出のために再コード
#--------------------------
groupn <- group
groupn[group == "統制群"]       <- 1
groupn[group == "失業・肯定"]   <- 2
groupn[group == "物価・肯定"]   <- 3
groupn[group == "成長・肯定"]   <- 4
groupn[group == "株価・肯定"]   <- 5
groupn[group == "失業・否定"]   <- 6
groupn[group == "物価・否定"]   <- 7
groupn[group == "成長・否定"]   <- 8
groupn[group == "株価・否定"]   <- 9

#------------------------------
# 加重算出のためにデータの設定
#------------------------------
dat8exp1 <- na.omit(data.frame(
  naeconch, busieconch, liveconch, cabapch,
  naeconps, busieconps, liveconps, cabapps,
  group, groupn, age, gender, education, income_group,
  psu_rul, psu,
  group_growth_negativen, group_growth_positiven,
  group_stock_negativen, group_stock_positiven,
  group_price_negativen, group_price_positiven,
  group_unemp_negativen, group_unemp_positiven,
  group_controln,
  psu_op, psu_indep,
  income,
  naeconch_or, busieconch_or, liveconch_or, cabapch_or
))

#------------------------------
# 傾向スコアの算出と加重算出
#------------------------------
W8_exp1 <- weightit(
  as.factor(groupn) ~ age + gender + income_group + education + psu_rul, 
  data = dat8exp1, 
  method = "ps", 
  estimand = "ATE",
  link = "logit"
)

dat8exp1$weights <- weights(W8_exp1)

# 全サンプルのweights合計をサンプル数に合わせてリスケール
total_weights <- sum(dat8exp1$weights)
dat8exp1$weights <- dat8exp1$weights / total_weights * nrow(dat8exp1)

#-----------------------
# データへの加重の付与
#-----------------------
weighted_data <- dat8exp1

# 「数値型」の変数かつ、後で除外指定していないものを選択
exclude_vars <- c("group_growth_negativen",
                  "group_growth_positiven",
                  "group_stock_negativen",
                  "group_stock_positiven",
                  "group_price_negativen",
                  "group_price_positiven",
                  "group_unemp_negativen",
                  "group_unemp_positiven",
                  "group_controln",
                  "psu_op",
                  "psu_indep",
                  "psu_rul",
                  "psu",
                  "group", "groupn",
                  "naeconch_or",
                  "busieconch_or",
                  "liveconch_or",
                  "cabapch_or")

numeric_vars <- names(weighted_data)[
  sapply(weighted_data, is.numeric) & 
    !(names(weighted_data) %in% exclude_vars)
]

# 変数 "weights" 自体は除外(割り算してはいけないので)
numeric_vars <- numeric_vars[numeric_vars != "weights"]

# 選ばれた数値変数について、weightsで割る
weighted_data[numeric_vars] <- lapply(weighted_data[numeric_vars], function(x) {
  x / weighted_data$weights
})

#----------------------------
# 加重付与済みデータの再成形
#----------------------------
# ここで weighted_data8exp1 が必要なので、weighted_data をコピー
weighted_data8exp1 <- weighted_data

dat8exp1w <- weighted_data8exp1 %>%
  dplyr::select(
    group,
    naeconch,
    busieconch,
    liveconch,
    cabapch,
    psu_rul,
    psu,
    naeconps,
    liveconps,
    busieconps,
    cabapps,
    group_growth_negativen,
    group_growth_positiven,
    group_stock_negativen,
    group_stock_positiven,
    group_price_negativen,
    group_price_positiven,
    group_unemp_negativen,
    group_unemp_positiven,
    group_controln,
    psu_op,
    psu_indep,
    age,
    gender,
    income,
    education,
    naeconch_or,
    busieconch_or,
    liveconch_or,
    cabapch_or
  ) %>%
  na.omit()

colnames(dat8exp1w) <- c(
  "group", "naeconch", "busieconch", "liveconch", "cabapch", "psu_rul", "psu",
  "naeconps", "liveconps", "busieconps", "cabapps",
  "group_growth_negativen", "group_growth_positiven",
  "group_stock_negativen", "group_stock_positiven",
  "group_price_negativen", "group_price_positiven",
  "group_unemp_negativen", "group_unemp_positiven",
  "group_controln", "psu_op", "psu_indep",
  "age", "gender", "income", "education",
  "naeconch_or", "busieconch_or", "liveconch_or", "cabapch_or"
)

【追試】図8-4:処置ごとでの平均値の差(事前質問から事後質問への変化)

一般的な傾向スコアをもとに、各種の推定を追試した結果を下記に示した。いずれにおいても、本文での分析結果と乖離せず、本文での分析結果を支持できるものとなっている。

【追試】図8-5:処置と党派性ごとでの経済評価変化値の平均値の差(国レベルでの経済評価)

【追試】図8-5:処置と党派性ごとでの経済評価変化値の平均値の差(景気評価)

【追試】図8-6:処置と党派性ごとでの経済評価変化値の平均値の差(暮らし向き評価)

【追試】図8-8:処置に対する反応の党派性差異(国レベルの経済評価)

【追試】図8-9:処置に対する反応の党派性差異(景気評価)

【追試】図8-10:処置に対する反応の党派性差異(暮らし向き評価)

エントロピー・バランシングによるデータへの重みづけ

以下では、エントロピー・バランシングにより、処置群に対して重みを付与するための計算を行う。統制群の重みを1とし、処置群に対して、eb.out$wを割り当てるための計算となる。

#------------------------------
# 加重算出のためにデータの設定
#------------------------------
dat8exp1eb <- na.omit(data.frame(
  naeconch, busieconch, liveconch, cabapch,
  naeconps, busieconps, liveconps, cabapps,
  group, groupn, age, gender, education, income_group,
  psu_rul, psu,
  group_growth_negativen, group_growth_positiven,
  group_stock_negativen, group_stock_positiven,
  group_price_negativen, group_price_positiven,
  group_unemp_negativen, group_unemp_positiven,
  group_controln,
  psu_op, psu_indep,
  income,
  naeconch_or, busieconch_or, liveconch_or, cabapch_or
))

dat8exp1eb <- dat8exp1eb %>%
  mutate(
    treat = ifelse(groupn == 1, 0, 1)
  )


#--------------------------------------------
# エントロピー・バランシングによる加重の算出
#--------------------------------------------
X <- as.matrix(dat8exp1eb %>% dplyr::select(age, gender, income_group, education, psu_rul))

invisible(
  capture.output(
eb.out <- ebal::ebalance(Treatment = dat8exp1eb$treat, X = X)
  )
)

weighted_data8exp1eb <- dat8exp1eb %>%
  mutate(
    ebal_weights = ifelse(treat == 1, eb.out$w, 1)
  )

total_weights <- sum(weighted_data8exp1eb$ebal_weights)
total_n <- nrow(weighted_data8exp1eb)
weighted_data8exp1eb <- weighted_data8exp1eb %>%
  mutate(
    ebal_weights_nm = ebal_weights / total_weights * total_n
  )

#-----------------------
# データへの加重の付与
#-----------------------
exclude_vars <- c("group_growth_negativen",
                  "group_growth_positiven",
                  "group_stock_negativen",
                  "group_stock_positiven",
                  "group_price_negativen",
                  "group_price_posivitens",  
                  "group_price_negativen",   
                  "group_price_positiven",
                  "group_unemp_negativen",
                  "group_unemp_positiven",
                  "group_controln",
                  "psu_op",
                  "psu_indep",
                  "psu_rul",
                  "psu",
                  "group", 
                  "groupn",
                  "naeconch_or",
                  "busieconch_or",
                  "liveconch_or",
                  "cabapch_or",
                  "ebal_weights",   
                  "ebal_weights_nm" ,
                  "treat"
)

numeric_vars <- names(weighted_data8exp1eb)[
  sapply(weighted_data8exp1eb, is.numeric) & !(names(weighted_data8exp1eb) %in% exclude_vars)
]

weighted_data8exp1eb[numeric_vars] <- lapply(weighted_data8exp1eb[numeric_vars], 
                                             function(x) x / weighted_data8exp1eb$ebal_weights_nm)


#----------------------------
# 加重付与済みデータの再成形
#----------------------------
dat8exp1web <- weighted_data8exp1eb %>%
  dplyr::select(
    group,
    naeconch,
    busieconch,
    liveconch,
    cabapch,
    psu_rul,
    psu,
    naeconps,
    liveconps,
    busieconps,
    cabapps,
    group_growth_negativen,
    group_growth_positiven,
    group_stock_negativen,
    group_stock_positiven,
    group_price_negativen,
    group_price_positiven,
    group_unemp_negativen,
    group_unemp_positiven,
    group_controln,
    psu_op,
    psu_indep,
    age,
    gender,
    income,
    education,
    naeconch_or,
    busieconch_or,
    liveconch_or,
    cabapch_or
  ) %>%
  na.omit()


colnames(dat8exp1web) <- c(
  "group", "naeconch", "busieconch", "liveconch", "cabapch", "psu_rul", "psu",
  "naeconps", "liveconps", "busieconps", "cabapps",
  "group_growth_negativen", "group_growth_positiven",
  "group_stock_negativen", "group_stock_positiven",
  "group_price_negativen", "group_price_positiven",
  "group_unemp_negativen", "group_unemp_positiven",
  "group_controln", "psu_op", "psu_indep",
  "age", "gender", "income", "education",
  "naeconch_or", "busieconch_or", "liveconch_or", "cabapch_or"
)

【追試】図8-4:処置ごとでの平均値の差(事前質問から事後質問への変化)

エントロピー・バランシングによる加重付与後の推定結果を、以下に示す。エントロピー・バランシングによる補正を行った後のデータでは、本文の結果と傾向スコアによる補正の結果とかなり異なる結果となっている。このように、エントロピー・バランシングに基づいた場合、本文の結果は支持されないが、ここではバランス・チェックにおいて、処置群と統制群間に統計的に有意な差がないことを念頭に、本文の結果が棄却されないと結論する。

【追試】図8-5:処置と党派性ごとでの経済評価変化値の平均値の差(国レベルでの経済評価))

【追試】図8-5:処置と党派性ごとでの経済評価変化値の平均値の差(景気評価)

【追試】図8-6:処置と党派性ごとでの経済評価変化値の平均値の差(暮らし向き評価)

【追試】図8-8:処置に対する反応の党派性差異(国レベルの経済評価)

【追試】図8-9:処置に対する反応の党派性差異(景気評価)

【追試】図8-10:処置に対する反応の党派性差異(暮らし向き評価)

実験8-2・データの前処理

#------------------
# データの読み込み
#------------------
dat8_exp2 <- read.csv("bisgaard_cint.csv", stringsAsFactors = FALSE)


#------------------
# 変数の設定
#------------------

#---- 処置変数(1) 
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    group_positive = if_else(Q5.1 == 1 | Q5.2 == 1, "肯定", as.character(Q5.1)),
    group_negative = if_else(Q6.1 == 1 | Q6.2 == 1, "否定", as.character(Q6.1)),
    group_control  = if_else(Q7.1 > 0, "統制", as.character(Q7.1))
  )

dat8_exp2 <- dat8_exp2 %>%
  mutate(
    group = coalesce(group_positive, group_negative, group_control)
  )

#---- 処置変数(2)
dat8_exp2$group_positiven <- ifelse(dat8_exp2$group == "肯定", 1, 0)
dat8_exp2$group_negativen <- ifelse(dat8_exp2$group == "否定", 1, 0)
dat8_exp2$group_controln  <- ifelse(dat8_exp2$group == "統制", 1, 0)

dat8_exp2 <- dat8_exp2 %>%
  mutate(
    group = coalesce(group_positive, group_negative, group_control)
  )


#---- 政党支持変数
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    psu = case_when(
      Q2.7 == 1 | Q2.7 == 3 ~ "与党派",
      Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ "野党派",
      Q2.7 == 17 ~ "無党派",
      Q2.7 %in% c(15, 16) ~ NA_character_,
      TRUE ~ NA_character_
    )
  )

#与党派
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    psu_rul = case_when(
      Q2.7 == 1 | Q2.7 == 3 ~ 1,
      Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ 0,
      Q2.7 == 17 ~ 0,
      Q2.7 %in% c(15, 16) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )

#野党派
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    psu_op = case_when(
      Q2.7 == 1 | Q2.7 == 3 ~ 0,
      Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ 1,
      Q2.7 == 17 ~ 0,
      Q2.7 %in% c(15, 16) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )

#無党派
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    psu_indep = case_when(
      Q2.7 == 1 | Q2.7 == 3 ~ 0,
      Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ 0,
      Q2.7 == 17 ~ 1,
      Q2.7 %in% c(15, 16) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )


#---- 経済評価
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    economic_sentiment = case_when(
      Q5.3 == 1 | Q6.3 == 1 ~ 5,
      Q5.3 == 2 | Q6.3 == 2 ~ 4,
      Q5.3 == 4 | Q6.3 == 4 ~ 2,
      Q5.3 == 5 | Q6.3 == 5 ~ 1,
      Q5.3 %in% c(6, 7) | Q6.3 %in% c(6, 7) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )

# GDP評価
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    gdp_evaluation = case_when(
      Q5.4 == 1 | Q6.4 == 1 | Q7.1 == 1 ~ 5,
      Q5.4 == 2 | Q6.4 == 2 | Q7.1 == 2 ~ 4,
      Q5.4 == 4 | Q6.4 == 4 | Q7.1 == 4 ~ 2,
      Q5.4 == 5 | Q6.4 == 5 | Q7.1 == 5 ~ 1,
      Q5.4 %in% c(6, 7) | Q6.4 %in% c(6, 7) | Q7.1 %in% c(6, 7) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )

#経済評価1年前比較
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    economy_evaluation_1year = case_when(
      Q5.5 == 1 | Q6.5 == 1 | Q7.2 == 1 ~ 5,
      Q5.5 == 2 | Q6.5 == 2 | Q7.2 == 2 ~ 4,
      Q5.5 == 4 | Q6.5 == 4 | Q7.2 == 4 ~ 2,
      Q5.5 == 5 | Q6.5 == 5 | Q7.2 == 5 ~ 1,
      Q5.5 %in% c(6, 7) | Q6.5 %in% c(6, 7) | Q7.2 %in% c(6, 7) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )

#景気評価
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    keiki_evaluation = case_when(
      Q5.6 == 1 | Q6.6 == 1 | Q7.3 == 1 ~ 5,
      Q5.6 == 2 | Q6.6 == 2 | Q7.3 == 2 ~ 4,
      Q5.6 == 4 | Q6.6 == 4 | Q7.3 == 4 ~ 2,
      Q5.6 == 5 | Q6.6 == 5 | Q7.3 == 5 ~ 1,
      Q5.6 %in% c(6, 7) | Q6.6 %in% c(6, 7) | Q7.3 %in% c(6, 7) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )

#暮らし向き評価
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    kurashimuki_evaluation = case_when(
      Q5.7 == 1 | Q6.7 == 1 | Q7.4 == 1 ~ 5,
      Q5.7 == 2 | Q6.7 == 2 | Q7.4 == 2 ~ 4,
      Q5.7 == 4 | Q6.7 == 4 | Q7.4 == 4 ~ 2,
      Q5.7 == 5 | Q6.7 == 5 | Q7.4 == 5 ~ 1,
      Q5.7 %in% c(6, 7) | Q6.7 %in% c(6, 7) | Q7.4 %in% c(6, 7) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )


#--- 内閣支持変数
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    cabap = case_when(
      Q8.2 == 1 ~ 5,
      Q8.2 == 2 ~ 4,
      Q8.2 == 4 ~ 2,
      Q8.2 == 5 ~ 1,
      Q8.2 %in% c(6, 7) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )


#---- 共変量
dat8_exp2 <- dat8_exp2 %>%
  mutate(
    age = Q2.2,
    income = Q3.1_1
  )

dat8_exp2 <- dat8_exp2 %>%
  mutate(
    income_group = case_when(
      income < 296 ~ 1,
      income >= 296 & income < 499 ~ 2,
      income >= 499 & income < 790 ~ 3,
      income >= 790 ~ 4,
      TRUE ~ NA_integer_
    )
  )

dat8_exp2 <- dat8_exp2 %>%
  mutate(
    gender = case_when(
      Q2.1 == 1 ~ 1,
      Q2.1 == 2 ~ 0,
      Q2.1 %in% c(3, 4) ~ NA_real_,
      TRUE ~ NA_real_
    )
  )

dat8_exp2 <- dat8_exp2 %>%
  mutate(
    education = case_when(
      Q2.4 < 3.01 ~ 0,
      Q2.4 > 3.99 ~ 1,
      Q2.4 %in% c(6, 7) ~ NA_real_,
      TRUE ~ as.numeric(Q2.4)
    )
  )

本文の補足分析と各図表のコード

図8-15:【実験8-2】党派性ごとでの各種経済評価の上昇程度

下記のコードは、効率化したものになっているが、細かなコードの詳細については、図8-17を参照。

#--------------
# データの設定
#--------------
dat8_exp2 <- na.omit(dat8_exp2 %>%
  dplyr::select(gdp_evaluation, age, education, gender, income,
                psu_rul, psu_op, psu_indep,
                group_controln, group_positiven, group_negativen,
                economy_evaluation_1year, keiki_evaluation, kurashimuki_evaluation))

#----------------
# 関数の読み込み
#----------------
source("plot8_exp2sim15.R")

#------------------------------
# シミュレーション前の各種設定
#------------------------------
evaluations <- c("gdp_evaluation", "economy_evaluation_1year",
                 "keiki_evaluation", "kurashimuki_evaluation")
titles <- c("GDP評価", "経済評価1年前比較", "景気評価", "暮らし向き評価")

party_vars <- c("psu_rul", "psu_op", "psu_indep")
parties <- c("与党派", "野党派", "無党派")
df <- dat8_exp2

#-----------------------------------
# シミュレーションとプロットの作成
#-----------------------------------
plots <- list()

for (i in 1:length(evaluations)) {
  sim_results <- lapply(party_vars, plot8_exp2sim, evaluation_name = evaluations[i])
  
  df_party <- do.call(rbind, sim_results)
  df_party <- data.frame("党派" = parties, df_party)
  colnames(df_party) <- c("党派", "coef", "low", "up")
  df_party$党派 <- factor(df_party$党派, levels = parties)
  
  df_party$highlight <- (df_party$low > 0 & df_party$up > 0) | (df_party$low < 0 & df_party$up < 0)
  
  p <- ggplot(df_party, aes(x = 党派, y = coef, ymin = low, ymax = up)) +
    geom_hline(yintercept = 0, linetype = "dashed") +
    
    geom_rect(data = subset(df_party, highlight == TRUE),
              aes(xmin = as.numeric(党派) - 0.15, xmax = as.numeric(党派) + 0.15,
                  ymin = low, ymax = up),
              fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
    
    geom_point(size = 3, shape = 21, fill = "white") +
    geom_errorbar(width = 0.2) +
    
    geom_text(data = subset(df_party, highlight == TRUE),
              aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
              hjust = -0.5, size = 3.5) +
    xlab("党派間での評価差") +
    
    ggtitle(titles[i]) +
    theme_bw()
  
  plots[[evaluations[i]]] <- p
}

#-----------------
# プロットの表示
#-----------------
do.call(grid.arrange, c(plots, ncol = 2))

図8-16:【実験8-2】党派性ごとでの各種経済評価の上昇程度

#--------------
# データの設定
#--------------
df <- dat8_exp2

#----------------
# 関数の読み込み
#----------------
source("plot8_exp2sim16.R") 
source("plot8_exp2df.R")
source("plot8_exp2.R")

#------------------------------
# シミュレーション前の各種設定
#------------------------------
party_vars <- c("psu_rul", "psu_op", "psu_indep")
result_names <- c("dfgdp_pos_party", "dfgdp_neg_party")
parties <- c("与党派", "野党派", "無党派")
article_types <- c("group_positiven", "group_negativen")
evaluations <- c("gdp_evaluation", "economy_evaluation_1year", "keiki_evaluation", "kurashimuki_evaluation")
titles <- c("GDP評価", "経済評価1年前比較", "景気評価", "暮らし向き評価")


#-----------------------------------
# シミュレーションとプロットの作成
#-----------------------------------
results <- list()

for (evaluation in evaluations) {
  for (article_type in article_types) {
    sim_results <- lapply(party_vars, plo8_exp2sim16, evaluation_name = evaluation, article_type = article_type)
    df_party <- do.call(rbind, sim_results)
    df_party <- data.frame(parties, df_party)
    colnames(df_party) <- c("党派", "coef", "low", "up")
    result_name <- paste0("df", evaluation, "_", article_type, "_party")
    results[[result_name]] <- df_party
  }
}

g <- list()

for (i in 1:length(evaluations)) {
  evaluation <- evaluations[i]
  df_pos <- plot8_exp2df(rbind(results[[paste0("df", evaluation, "_group_positiven_party")]]), "肯定記事")
  df_neg <- plot8_exp2df(rbind(results[[paste0("df", evaluation, "_group_negativen_party")]]), "否定記事")
  df <- data.frame(rbind(df_pos, df_neg))
  df <- transform(df, 党派=factor(党派, levels=c("与党派","野党派","無党派")))
  
  g[[i]] <- plot8_exp2(df, titles[i])
}

#-----------------
# プロットの表示
#-----------------
h1 <- h[[1]] 
h2 <- h[[2]] 
h3 <- h[[3]] 
h4 <- h[[4]] 

grid.arrange(h1, h2, h3, h4, ncol=2)

図8-17: 【実験8-2】党派性別、党派性と処置別での内閣支持の上昇程度

#------------------------------------
# 肯定的記事に関するシミュレーション
#------------------------------------

#---- 与党派シミュレーション
zpar_rul_pos <- zelig(cabap ~ income + gender + education + age + psu_rul + group_positiven + 
                        psu_rul:group_positiven, dat8_exp2, model = "normal")

x.notrul <- setx(zpar_rul_pos, psu_rul = 1, income = 503, gender = 0, education = 4, age = 32, group_positiven = 1)
x.rul <- setx(zpar_rul_pos, psu_rul = 1, income = 503, gender = 0, education = 4, age = 32, group_positiven = 0)
s.out <- sim(zpar_rul_pos, x = x.notrul, x1 = x.rul)
sim_pos_rul <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
sim_pos_rul_fd <- quantile(sim_pos_rul[, 1], c(0.5, .025, .975))

#---- 野党派シミュレーション
zpar_op_pos <- zelig(cabap ~ income + gender + education + age + psu_op + group_positiven + 
                       psu_op:group_positiven, df_par, model = "normal")

x.notrul <- setx(zpar_op_pos, psu_op = 1, income = 503, gender = 0, education = 4, age = 32, group_positiven = 0)
x.rul <- setx(zpar_op_pos, psu_op = 1, income = 503, gender = 0, education = 4, age = 32, group_positiven = 1)
s.out <- sim(zpar_op_pos, x = x.notrul, x1 = x.rul)
sim_pos_op <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
sim_pos_op_fd <- quantile(sim_pos_op[, 1], c(0.5, .025, .975))

#---- 無党派シミュレーション
zpar_indep_pos <- zelig(cabap ~ income + gender + education + age + psu_indep + group_positiven + 
                          psu_indep:group_positiven, df_par, model = "normal")

x.notrul <- setx(zpar_indep_pos, psu_indep = 1, income = 503, gender = 0, education = 4, age = 32, group_positiven = 0)
x.rul <- setx(zpar_indep_pos, psu_indep = 1, income = 503, gender = 0, education = 4, age = 32, group_positiven = 1)
s.out <- sim(zpar_indep_pos, x = x.notrul, x1 = x.rul)
sim_pos_indep <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
sim_pos_indep_fd <- quantile(sim_pos_indep[, 1], c(0.5, .025, .975))

#---- データフレームの設定:肯定的記事
dfkurashimuki_pos <- rbind(sim_pos_rul_fd, sim_pos_op_fd, sim_pos_indep_fd)
df_cabap_pos <- data.frame("記事種類" = "肯定記事", "党派" = c("与党派", "野党派", "無党派"), dfkurashimuki_pos)
colnames(df_cabap_pos) <- c("記事種類", "党派", "coef", "low", "up")

#------------------------------------
# 否定的記事に関するシミュレーション
#------------------------------------
#---- 与党派に関するシミュレーション
zpar_rul_neg <- zelig(cabap ~ income + gender + education + age + psu_rul + group_negativen +
                        psu_rul:group_negativen, df_par, model = "normal")

x.notrul <- setx(zpar_rul_neg, psu_rul = 1, income = 503, gender = 0, education = 4, age = 32, group_negativen = 0)
x.rul <- setx(zpar_rul_neg, psu_rul = 1, income = 503, gender = 0, education = 4, age = 32, group_negativen = 1)
s.out <- sim(zpar_rul_neg, x = x.notrul, x1 = x.rul)
sim_neg_rul <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
sim_neg_rul_fd <- quantile(sim_neg_rul[, 1], c(0.5, .025, .975))

#---- 野党派に関するシミュレーション
zpar_op_neg <- zelig(cabap ~ income + gender + education + age + psu_op + group_negativen +
                       psu_op:group_negativen, df_par, model = "normal")

x.notrul <- setx(zpar_op_neg, psu_op = 1, income = 503, gender = 0, education = 4, age = 32, group_negativen = 0)
x.rul <- setx(zpar_op_neg, psu_op = 1, income = 503, gender = 0, education = 4, age = 32, group_negativen = 1)
s.out <- sim(zpar_op_neg, x = x.notrul, x1 = x.rul)
sim_neg_op <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
sim_neg_op_fd <- quantile(sim_neg_op[, 1], c(0.5, .025, .975))

#---- 無党派に関するシミュレーション
zpar_indep_neg <- zelig(cabap ~ income + gender + education + age + psu_indep + group_negativen +
                          psu_indep:group_negativen, df_par, model = "normal")

x.notrul <- setx(zpar_indep_neg, psu_indep = 1, income = 503, gender = 0, education = 4, age = 32, group_negativen = 0)
x.rul <- setx(zpar_indep_neg, psu_indep = 1, income = 503, gender = 0, education = 4, age = 32, group_negativen = 1)
s.out <- sim(zpar_indep_neg, x = x.notrul, x1 = x.rul)
sim_neg_indep <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
sim_neg_indep_fd <- quantile(sim_neg_indep[, 1], c(0.5, .025, .975))

#---- データフレームの設定:否定的記事
dfkurashimuki_neg <- rbind(sim_neg_rul_fd, sim_neg_op_fd, sim_neg_indep_fd)
df_cabap_neg <- data.frame("記事種類" = "否定記事", "党派" = c("与党派", "野党派", "無党派"), dfkurashimuki_neg)
colnames(df_cabap_neg) <- c("記事種類", "党派", "coef", "low", "up")


#--------------------
# データセットの整理
#--------------------
df_cabap <- data.frame(rbind(df_cabap_pos, df_cabap_neg))
df_cabap$highlight <- with(df_cabap, (low > 0 & up > 0) | (low < 0 & up < 0))

#---- プロット1: 党派別
dfcabap_party <- transform(dfcabap_party, 党派 = factor(党派, levels = c("与党派", "野党派", "無党派")))

dfcabap_party$highlight <- with(dfcabap_party, (low > 0 & up > 0) | (low < 0 & up < 0))

h1 <- ggplot(data = dfcabap_party, aes(y = coef, x = 党派, ymin = low, ymax = up)) +
  geom_hline(yintercept = 0, color = "black", size = 0.5) +
  
  geom_rect(data = subset(dfcabap_party, highlight == TRUE),
            aes(xmin = as.numeric(党派) - 0.15, xmax = as.numeric(党派) + 0.15, ymin = low, ymax = up),
            fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
  
  geom_errorbar(size = 0.2, width = 0.1, linetype = 1, color = "black") +
  geom_point(size = 3, shape = 21, fill = "white") +
  geom_line() +
  
  geom_text(data = subset(dfcabap_party, highlight == TRUE),
            aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
            hjust = -0.3, vjust = -0.5, size = 3.5) +
  
  xlab("党派") + ylab("党派別での評価差") +
  ggtitle("党派別") + theme_bw() +
  theme(legend.position = c(0.1, 0.1), legend.key.size = unit(0.3, "cm"))


#---- プロット2: 党派別×処置別
df_cabap <- transform(df_cabap, 党派 = factor(党派, levels = c("与党派", "野党派", "無党派")))

df_cabap$highlight <- with(df_cabap, (low > 0 & up > 0) | (low < 0 & up < 0))

pd <- position_dodge(0.2)
h2 <- ggplot(data = df_cabap, aes(y = coef, x = 党派, ymin = low, ymax = up, linetype = 記事種類, group = 記事種類, fill = 記事種類)) +
  geom_hline(yintercept = 0, color = "black", size = 0.5) +
  
  geom_rect(data = subset(df_cabap, highlight == TRUE),
            aes(xmin = as.numeric(党派) - 0.15, xmax = as.numeric(党派) + 0.15, ymin = low, ymax = up),
            fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
  
  geom_errorbar(size = 0.2, width = 0.1, linetype = 1, color = "black", position = pd) +
  geom_point(size = 3, shape = 21, fill = "white", position = pd) +
  geom_line(position = pd) +
  
  geom_text(data = subset(df_cabap, highlight == TRUE),
            aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
            hjust = -0.5, size = 3.5, position = pd) +
  
  xlab("党派") + ylab("") +
  ggtitle("党派性×処置別") + theme_bw() +
  theme(axis.text = element_text(size = 10, color = "black"),
        axis.text.y = element_text(size = 8, color = "black"),
        plot.title = element_text(hjust = 0.5, face = "bold"))

#----------------
# プロットの表示
#----------------
windows(200, 100)
grid.arrange(h1, h2, ncol = 2)

【実験8-2】データの検討:バランス・チェックと加重付与による追試)

バランス・チェック

バランス・チェックによれば、群間で主要な変数間の分布に統計的な有意差がなく、群間の単位同質性が著しく侵害されていることを示す結果とはなっていない。しかし、群間で完全な均質性が保たれているわけではないことから、一般的な傾向スコア、エントロピー・バランシングによって、データを重みづけした推定結果を、参考として示す。

#-------------------------
#バランス・チェックの実行
#-------------------------
dat8_exp2_bc <-  na.omit(data.frame(group, age, gender, education, income_group, psu_rul ))
tb_bc2 <- sumtable(dat8_exp2_bc, group = "group", group.test = TRUE, title = "")

実験8-2のバランス・チェックの結果

Table 2:
group
肯定
統制
否定
Variable N Mean SD N Mean SD N Mean SD Test
age 664 33 16 698 33 16 618 32 16 F=0.634
gender 664 0.52 0.5 698 0.51 0.5 618 0.48 0.5 F=1.065
education 664 0.47 0.5 698 0.44 0.5 618 0.46 0.5 F=0.805
income_group 664 2.5 1.1 698 2.5 1.1 618 2.5 1.1 F=0.02
psu_rul 664 0.24 0.43 698 0.22 0.42 618 0.23 0.42 F=0.165
Statistical significance markers: * p<0.1; ** p<0.05; *** p<0.01

傾向スコアによるデータへの重みづけ

#------------------------------------------
# 加重算出のためのグループ変数の再コード化
#------------------------------------------
groupn <- group
groupn[group == "統制"] <- 1
groupn[group == "肯定"] <- 2
groupn[group == "否定"] <- 3

#------------------------------
# 加重算出のためのデータの設定
#------------------------------
dat8_exp2_15 <- na.omit(data.frame(
  gdp_evaluation, age, education, gender, income, income_group,
  psu_rul, psu_op, psu_indep,
  group_controln, group_positiven, group_negativen, groupn,
  economy_evaluation_1year, keiki_evaluation, kurashimuki_evaluation
))

#------------------------------
# 傾向スコアの算出と加重算出
#------------------------------
W.out <- weightit(as.factor(groupn) ~ age + gender + income_group + education + psu_rul, 
                  data = dat8_exp2_15, 
                  method = "ps", 
                  estimand = "ATE",
                  link = "logit")

dat8_exp2_15$weights <- weights(W.out)

total_weights <- sum(dat8_exp2_15$weights)
dat8_exp2_15$weights <- dat8_exp2_15$weights / total_weights * nrow(dat8_exp2_15)

#-----------------------
# データへの加重の付与
#-----------------------
weighted_data <- dat8_exp2_15
numeric_vars <- sapply(weighted_data, is.numeric)
numeric_vars["weights"] <- FALSE  

exclude_vars <- c("psu_rul", "psu_op", "psu_indep", 
                  "group_controln", "group_positiven", "group_negativen", "groupn")

numeric_vars <- names(weighted_data)[sapply(weighted_data, is.numeric) & 
                                      !(names(weighted_data) %in% exclude_vars)]

weighted_data[numeric_vars] <- lapply(weighted_data[numeric_vars], 
                                      function(x) x / weighted_data$weights)
#----------------------------
# 加重付与済みデータの再成形
#----------------------------
dat8exp2w <- weighted_data %>%
  dplyr::select(
    gdp_evaluation, age, education, gender, income, income_group,
    psu_rul, psu_op, psu_indep,
    group_controln, group_positiven, group_negativen, groupn,
    economy_evaluation_1year, keiki_evaluation, kurashimuki_evaluation
  ) %>%
  na.omit()

colnames(dat8exp2w) <- c(
  "gdp_evaluation", "age", "education", "gender", "income", "income_group",
  "psu_rul", "psu_op", "psu_indep",
  "group_controln", "group_positiven", "group_negativen", "groupn",
  "economy_evaluation_1year", "keiki_evaluation", "kurashimuki_evaluation"
)

【追試】図8-15:党派性ごとでの各種経済評価の上昇程度)

傾向スコアによる重みづけを行ったとのデータを用いた場合に、(1)GDP評価での党派性差異が確認され、(2)与党派の効果がより高まるという変化が見て取れる(図8-15)。さらに、本文の結果とは異なり、(3)否定的情報に対する効果量が肯定的情報に対する効果量よりも大きく、(4)与党派で最大になっている。本結果は、不平の非対称性を直ちに支持する結果ではない。但し、本文の推定結果を棄却するものではない点も注目を要する。

【追試】図8-16:党派性ごとでの各種経済評価の上昇程度)

エントロピー・バランシングによるデータへの重みづけ

以下では、エントロピー・バランシングにより、処置群に対して重みを付与するための計算を行う。統制群の重みを1とし、処置群に対して、eb.out$wを割り当てるための計算となる。

#--------------------------
# 加重算出のためのグループ変数の再コード化
#--------------------------
groupn <- group
groupn[group == "統制"] <- 1
groupn[group == "肯定"] <- 2
groupn[group == "否定"] <- 3

#------------------------------
# 加重算出のためのデータの設定
#------------------------------
dat8_exp2_15 <- na.omit(data.frame(
  gdp_evaluation, age, education, gender, income, income_group,
  psu_rul, psu_op, psu_indep,
  group_controln, group_positiven, group_negativen, groupn,
  economy_evaluation_1year, keiki_evaluation, kurashimuki_evaluation
))

# 治療群(treat)を作成:統制群(groupn==1)は 0、それ以外は1
dat8_exp2_15$treat <- ifelse(dat8_exp2_15$groupn == 1, 0, 1)

#--------------------------------------------
# エントロピー・バランシングによる加重の算出
#--------------------------------------------
X <- as.matrix(dat8_exp2_15 %>% dplyr::select(age, gender, income_group, education, psu_rul))

invisible(
  capture.output(
eb.out <- ebal::ebalance(Treatment = dat8_exp2_15$treat, X = X)
  )
)

dat8_exp2_15 <- dat8_exp2_15 %>%
  mutate(
    ebal_weights = ifelse(treat == 1, eb.out$w, 1)
  )

#-----------------------
# 重みの正規化
#-----------------------
total_weights <- sum(dat8_exp2_15$ebal_weights)
total_n <- nrow(dat8_exp2_15)
dat8_exp2_15 <- dat8_exp2_15 %>%
  mutate(
    ebal_weights_nm = ebal_weights / total_weights * total_n
  )

#-----------------------
# データへの加重の付与
#-----------------------
weighted_data <- dat8_exp2_15
numeric_vars <- sapply(weighted_data, is.numeric)
numeric_vars["ebal_weights_nm"] <- FALSE  

exclude_vars <- c("psu_rul", "psu_op", "psu_indep", 
                  "group_controln", "group_positiven", "group_negativen", "groupn")

numeric_vars <- names(weighted_data)[sapply(weighted_data, is.numeric) & 
                                      !(names(weighted_data) %in% exclude_vars)]

weighted_data[numeric_vars] <- lapply(weighted_data[numeric_vars], 
                                      function(x) x / weighted_data$ebal_weights_nm)

#----------------------------
# 加重付与済みデータの再成形
#----------------------------
dat8exp2w <- weighted_data %>%
  dplyr::select(
    gdp_evaluation, age, education, gender, income, income_group,
    psu_rul, psu_op, psu_indep,
    group_controln, group_positiven, group_negativen, groupn,
    economy_evaluation_1year, keiki_evaluation, kurashimuki_evaluation
  ) %>%
  na.omit()

colnames(dat8exp2w) <- c(
  "gdp_evaluation", "age", "education", "gender", "income", "income_group",
  "psu_rul", "psu_op", "psu_indep",
  "group_controln", "group_positiven", "group_negativen", "groupn",
  "economy_evaluation_1year", "keiki_evaluation", "kurashimuki_evaluation"
)

【追試】図8-15:党派性ごとでの各種経済評価の上昇程度

エントロピー・バランシングによる加重付与後のデータを用いた場合にも、各種経済評価の上昇程度の党派性差異に関する結果は、本文と大きく乖離しない。ここでも、与党派の効果がさらに大きいという結果である(図8-15)。さらに、傾向スコアによる加重を付与した場合と類似して、否定的情報の効果量の方が肯定黄な情報の効果量よりも大きい傾向が見て取れる。本文で示されなかった不平の非対称を支持する結果とは結論できないが、少なくとも本文の推定結果は棄却されない(否定的な情報に接触した際に否定的な方向に評価が転じるという点において)。

【追試】図8-16:党派性ごとでの各種経済評価の上昇程度

第9章:経済情報をどのように推論・表明しているのか?―実験データの分析(2)

実験9-1・データの前処理

# ----------------
# データの読み込み
# ----------------
dat9_exp1 <- read.csv("prm_guay_cint.csv", stringsAsFactors = FALSE)


# ------------
# 変数の設定
# ------------
#----失業率関連(与党寄り)
dat9_exp1 <- dat9_exp1 %>% 
  mutate(unem_rul = case_when(
    Q9.1 == 1 ~ 1,
    Q9.1 == 2 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(unem_ruln = case_when(
    Q9.1 == 1 ~ "与党失業1",
    Q9.1 == 2 ~ "非与党失業1",
    TRUE ~ NA_character_
  ))

#----失業率関連(非与党寄り)
dat9_exp1 <- dat9_exp1 %>% 
  mutate(unem_norul = case_when(
    Q8.1 == 2 ~ 1,
    Q8.1 == 1 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(unem_noruln = case_when(
    Q8.1 == 2 ~ "与党失業2",
    Q8.1 == 1 ~ "非与党失業2",
    TRUE ~ NA_character_
  ))

#----物価関連(与党寄り)
dat9_exp1 <- dat9_exp1 %>% 
  mutate(price_rul = case_when(
    Q12.1 %in% c(1,2) ~ 1,
    Q12.1 %in% c(4,5) ~ 0,
    Q12.1 == 3 ~ NA_real_,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(price_ruln = case_when(
    Q12.1 %in% c(1,2) ~ "与党物価1",
    Q12.1 %in% c(4,5) ~ "非与党物価1",
    Q12.1 == 3 ~ NA_character_,
    TRUE ~ NA_character_
  ))

#----物価関連(非与党寄り)
dat9_exp1 <- dat9_exp1 %>% 
  mutate(price_norul = case_when(
    Q13.1 == 2 ~ 1,
    Q13.1 == 1 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(price_noruln = case_when(
    Q13.1 == 2 ~ "与党物価2",
    Q13.1 == 1 ~ "非与党物価2",
    TRUE ~ NA_character_
  ))


#----失業・物価に関するグループの整理
dat9_exp1 <- dat9_exp1 %>% 
  mutate(group_unemp = case_when(
    Q9.1 == 1 ~ "失業・与党",
    Q8.1 == 1 ~ "失業・非与党",
    Q12.1 == 1 ~ "物価・与党",
    Q13.1 == 1 ~ "物価・非与党",
    TRUE ~ NA_character_
  ))

#----外国人労働者関連
dat9_exp1 <- dat9_exp1 %>% 
  mutate(foreign_rul = case_when(
    Q16.1 %in% c(1,2) ~ 0,
    Q16.1 %in% c(4,5) ~ 1,
    Q16.1 == 3 ~ NA_real_,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(foreign_ruln = case_when(
    Q16.1 %in% c(1,2) ~ "非与党外国1",
    Q16.1 %in% c(4,5) ~ "与党外国1",
    Q16.1 == 3 ~ NA_character_,
    TRUE ~ NA_character_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(foreign_norul = case_when(
    Q17.1 == 2 ~ 1,
    Q17.1 == 1 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(foreign_noruln = case_when(
    Q17.1 == 2 ~ "与党外国2",
    Q17.1 == 1 ~ "非与党外国2",
    TRUE ~ NA_character_
  ))

#----LGBTQ関連
dat9_exp1 <- dat9_exp1 %>% 
  mutate(lgbtq_rul = case_when(
    Q20.1 == 1 ~ 1,
    Q20.1 == 2 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(lgbtq_ruln = case_when(
    Q20.1 == 1 ~ "与党LG1",
    Q20.1 == 2 ~ "非与党LG1",
    TRUE ~ NA_character_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(lgbtq_norul = case_when(
    Q21.1 == 2 ~ 1,
    Q21.1 == 1 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(lgbtq_noruln = case_when(
    Q21.1 == 2 ~ "与党LG2",
    Q21.1 == 1 ~ "非与党LG2",
    TRUE ~ NA_character_
  ))

#----外国人・LGBTQに関するグループの整理
dat9_exp1 <- dat9_exp1 %>% 
  mutate(group_foreign = case_when(
    Q16.1 == 1 ~ "外国人・与党",
    Q17.1 == 1 ~ "外国人・非与党",
    Q20.1 == 1 ~ "LGBTQ・与党",
    Q21.1 == 1 ~ "LGBTQ・非与党",
    TRUE ~ "LGBTQ・非与党"
  ))


#----経済投票関連
dat9_exp1 <- dat9_exp1 %>% 
  mutate(ev_rul = case_when(
    Q24.1 == 1 ~ 1,
    Q24.1 == 2 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(ev_ruln = case_when(
    Q24.1 == 1 ~ "与党経済1",
    Q24.1 == 2 ~ "非与党経済1",
    TRUE ~ NA_character_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(ev_norul = case_when(
    Q25.1 == 2 ~ 1,
    Q25.1 == 1 ~ 0,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(ev_noruln = case_when(
    Q25.1 == 2 ~ "与党経済2",
    Q25.1 == 1 ~ "非与党経済2",
    TRUE ~ NA_character_
  ))

#----経済投票グループの作成
dat9_exp1 <- dat9_exp1 %>% 
  mutate(group_ev = case_when(
    Q24.1 == 1 ~ "経済投票・与党",
    Q25.1 == 1 ~ "経済投票・非与党",
    TRUE ~ NA_character_
  ))

#----他各種変数の作成
# 内閣支持
dat9_exp1 <- dat9_exp1 %>% 
  mutate(cabap = case_when(
    Q4.1 == 1 ~ 5,
    Q4.1 == 2 ~ 4,
    Q4.1 == 4 ~ 2,
    Q4.1 == 5 ~ 1,
    Q4.1 %in% c(6,7) ~ NA_real_,
    TRUE ~ NA_real_
  ))

#政党支持変数
dat9_exp1 <- dat9_exp1 %>% 
  mutate(psu = case_when(
    Q2.7 %in% c(1,3) ~ "与党派",
    Q2.7 %in% c(2,4,5,6,7,8,9) ~ "野党派",
    Q2.7 == 10 ~ "無党派",
    Q2.7 %in% c(11,12) ~ NA_character_,
    TRUE ~ NA_character_
  ))

#与党派
dat9_exp1 <- dat9_exp1 %>% 
  mutate(psu_rul = case_when(
    Q2.7 %in% c(1,3) ~ 1,
    Q2.7 %in% c(2,4,5,6,7,8,9) ~ 0,
    Q2.7 == 10 ~ 0,
    Q2.7 %in% c(11,12) ~ NA_real_,
    TRUE ~ NA_real_
  ))

#野党派
dat9_exp1 <- dat9_exp1 %>% 
  mutate(psu_op = case_when(
    Q2.7 %in% c(1,3) ~ 0,
    Q2.7 %in% c(2,4,5,6,7,8,9) ~ 1,
    Q2.7 == 10 ~ 0,
    Q2.7 %in% c(11,12) ~ NA_real_,
    TRUE ~ NA_real_
  ))

#無党派
dat9_exp1 <- dat9_exp1 %>% 
  mutate(psu_indep = case_when(
    Q2.7 %in% c(1,3) ~ 0,
    Q2.7 %in% c(2,4,5,6,7,8,9) ~ 0,
    Q2.7 == 10 ~ 1,
    Q2.7 %in% c(11,12) ~ NA_real_,
    TRUE ~ NA_real_
  ))

#イデオロギー変数
dat9_exp1 <- dat9_exp1 %>% 
  mutate(ideology = case_when(
    Q6.1_1 %in% c(1,2,3,4) ~ 1,
    Q6.1_1 %in% c(5,6) ~ 2,
    Q6.1_1 %in% c(7,8,9,10) ~ 3,
    TRUE ~ NA_real_
  ))

#政策位置変数
dat9_exp1 <- dat9_exp1 %>% 
  mutate(unem_issue = Q5.1)

dat9_exp1 <- dat9_exp1 %>% 
  mutate(lgbtq_issue = Q5.4)

dat9_exp1 <- dat9_exp1 %>% 
  mutate(ev_issue = case_when(
    Q5.5 == 5 ~ 1,
    Q5.5 == 4 ~ 2,
    Q5.5 == 2 ~ 4,
    Q5.5 == 1 ~ 5,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(price_issue = Q5.2)

dat9_exp1 <- dat9_exp1 %>% 
  mutate(foreign_issue = Q5.3)

#----共変量の作成
dat9_exp1 <- dat9_exp1 %>% 
  mutate(age = Q2.2)

dat9_exp1 <- dat9_exp1 %>% 
  mutate(income = Q3.1_1)

dat9_exp1 <- dat9_exp1 %>% 
  mutate(income_group = case_when(
    income < 287 ~ 1,
    income >= 287 & income < 489 ~ 2,
    income >= 489 & income < 606.5 ~ 3,
    income >= 770 ~ 4,
    TRUE ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(gender = case_when(
    Q2.1 == 1 ~ 1,
    Q2.1 == 2 ~ 0,
    Q2.1 %in% c(3,4) ~ NA_real_
  ))

dat9_exp1 <- dat9_exp1 %>% 
  mutate(education = case_when(
    Q2.4 %in% c(4,5) ~ 4,
    Q2.4 %in% c(6,7) ~ NA_real_,
    TRUE ~ as.numeric(Q2.4)
  ))

本文の補足分析と各図表のコード

図9-4:【実験9-1】党派性、イデオロギー、政策位置ごとでの党派的情報推論での正答確率(経済政策領域)

#---------------
# 関数の読み込み
#---------------
source("plot9_exp1hl.R")
source("plot9_exp1.R")

#--------------------------------
# 最低賃金と失業率:党派性ごと
#--------------------------------

# 与党寄りのシミュレーション
df_unemp <- data.frame(unem_rul = dat9_exp1$unem_rul,
                       psu_rul = dat9_exp1$psu_rul,
                       ideology = dat9_exp1$ideology,
                       education = dat9_exp1$education,
                       gender = dat9_exp1$gender,
                       income = dat9_exp1$income,
                       age = dat9_exp1$age)
z_unem_rul <- zelig(unem_rul ~ psu_rul + age + gender + income + education, 
                    data = na.omit(df_unemp), model = "logit", cite = FALSE)
x.notrul <- setx(z_unem_rul, psu_rul = 0)
x.rul    <- setx(z_unem_rul, psu_rul = 1)
s.out_rul <- sim(z_unem_rul, x = x.notrul, x1 = x.rul)
df_sim <- as.data.frame(zelig_qi_to_df(s.out_rul))
data_rul <- subset(df_sim, psu_rul == 1)
rulunem_rul_par <- quantile(data_rul$expected_value, c(0.5, 0.025, 0.975))
data_norul <- subset(df_sim, psu_rul == 0)
rulunem_norul_par <- quantile(data_norul$expected_value, c(0.5, 0.025, 0.975))

# 非与党寄りのシミュレーション
df_unemp <- data.frame(unem_norul = dat9_exp1$unem_norul,
                       psu_rul = dat9_exp1$psu_rul,
                       ideology = dat9_exp1$ideology,
                       education = dat9_exp1$education,
                       gender = dat9_exp1$gender,
                       income = dat9_exp1$income,
                       age = dat9_exp1$age)
z_unem_norul <- zelig(unem_norul ~ psu_rul + age + gender + income + education, 
                      data = na.omit(df_unemp), model = "logit", cite = FALSE)
x.notrul <- setx(z_unem_norul, psu_rul = 0)
x.rul    <- setx(z_unem_norul, psu_rul = 1)
s.out_norul <- sim(z_unem_norul, x = x.notrul, x1 = x.rul)
df_sim <- as.data.frame(zelig_qi_to_df(s.out_norul))
data_rul <- subset(df_sim, psu_rul == 1)
norulunem_rul_par <- quantile(data_rul$expected_value, c(0.5, 0.025, 0.975))
data_norul <- subset(df_sim, psu_rul == 0)
norulunem_norul_par <- quantile(data_norul$expected_value, c(0.5, 0.025, 0.975))

# プロット用のデータ作成(被験者党派性別)
data1 <- data.frame(rbind(rulunem_rul_par, rulunem_norul_par, 
                          norulunem_rul_par, norulunem_norul_par))
colnames(data1) <- c("mean", "low", "up")
data1$情報の党派性 <- c("与党寄り", "与党寄り", "非与党寄り", "非与党寄り")
data1$被験者党派性 <- c("与党派", "非与党派", "与党派", "非与党派")
data1$情報の党派性 <- factor(data1$情報の党派性, levels = c("与党寄り", "非与党寄り"))
data1$被験者党派性 <- factor(data1$被験者党派性, levels = c("与党派", "非与党派"))
data1 <- plot9_exp1hl(data1)
j1 <- plot9_exp1(data1, "被験者党派性", "mean", "情報の党派性", "情報の党派性",
                          "被験者の党派性", "正答確率", "【最低賃金】:党派性")

#-----------------
#イデオロギーごと
#-----------------
# 与党寄りのシミュレーション
df_unemp <- data.frame(unem_rul = dat9_exp1$unem_rul,
                       ideology = dat9_exp1$ideology,
                       education = dat9_exp1$education,
                       gender = dat9_exp1$gender,
                       income = dat9_exp1$income,
                       age = dat9_exp1$age)
z_unem_rul <- zelig(unem_rul ~ ideology + age + gender + income + education, 
                    data = na.omit(df_unemp), model = "logit", cite = FALSE)
x.left  <- setx(z_unem_rul, ideology = 1)
x.mod   <- setx(z_unem_rul, ideology = 2)
x.right <- setx(z_unem_rul, ideology = 3)
s.out_rul_idelef <- sim(z_unem_rul, x = x.left)
s.out_rul_idemod <- sim(z_unem_rul, x = x.mod)
s.out_rul_iderig <- sim(z_unem_rul, x = x.right)
df_sim <- as.data.frame(zelig_qi_to_df(s.out_rul_idelef))
rulunem_lef_par <- quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))
df_sim <- as.data.frame(zelig_qi_to_df(s.out_rul_idemod))
rulunem_mod_par <- quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))
df_sim <- as.data.frame(zelig_qi_to_df(s.out_rul_iderig))
rulunem_rig_par <- quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))

# 非与党寄りのシミュレーション
df_unemp <- data.frame(unem_norul = dat9_exp1$unem_norul,
                       ideology = dat9_exp1$ideology,
                       education = dat9_exp1$education,
                       gender = dat9_exp1$gender,
                       income = dat9_exp1$income,
                       age = dat9_exp1$age)
z_unem_norul <- zelig(unem_norul ~ ideology + age + gender + income + education, 
                      data = na.omit(df_unemp), model = "logit", cite = FALSE)
x.left  <- setx(z_unem_norul, ideology = 1)
x.mod   <- setx(z_unem_norul, ideology = 2)
x.right <- setx(z_unem_norul, ideology = 3)
s.out_norul_idelef <- sim(z_unem_norul, x = x.left)
s.out_norul_idemod <- sim(z_unem_norul, x = x.mod)
s.out_norul_iderig <- sim(z_unem_norul, x = x.right)
df_sim <- as.data.frame(zelig_qi_to_df(s.out_norul_idelef))
norulunem_lef_par <- quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))
df_sim <- as.data.frame(zelig_qi_to_df(s.out_norul_idemod))
norulunem_mod_par <- quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))
df_sim <- as.data.frame(zelig_qi_to_df(s.out_norul_iderig))
norulunem_rig_par <- quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))

# プロット用のデータ作成(被験者イデオロギー別)
data2 <- data.frame(rbind(rulunem_lef_par, rulunem_mod_par, rulunem_rig_par, 
                          norulunem_lef_par, norulunem_mod_par, norulunem_rig_par))
colnames(data2) <- c("mean", "low", "up")
data2$情報の党派性 <- rep(c("与党寄り", "非与党寄り"), each = 3)
data2$被験者イデオロギー <- rep(c("左派", "中道", "右派"), times = 2)
data2$被験者イデオロギー <- factor(data2$被験者イデオロギー, levels = c("左派", "中道", "右派"))
data2$情報の党派性 <- factor(data2$情報の党派性, levels = c("与党寄り", "非与党寄り"))
data2 <- plot9_exp1hl(data2)
j2 <- plot9_exp1(data2, "被験者イデオロギー", "mean", "情報の党派性", "情報の党派性",
                           "被験者のイデオロギー", "", "イデオロギー")

#-----------------------------------
#イシュー位置ごとのシミュレーション
#-----------------------------------
# 与党寄りのシミュレーション
df_unemp <- data.frame(unem_rul = dat9_exp1$unem_rul,
                       unem_issue = dat9_exp1$unem_issue,
                       education = dat9_exp1$education,
                       gender = dat9_exp1$gender,
                       income = dat9_exp1$income,
                       age = dat9_exp1$age)
z_unem_rul <- zelig(unem_rul ~ unem_issue + age + gender + income + education, 
                    data = na.omit(df_unemp), model = "logit", cite = FALSE)
x_list <- list()
for (i in 1:5) {
  x_list[[i]] <- setx(z_unem_rul, unem_issue = i)
}
s.out_rul_list <- lapply(x_list, function(x) sim(z_unem_rul, x = x))
rulunem_par_list <- lapply(s.out_rul_list, function(s.out) {
  df_sim <- as.data.frame(zelig_qi_to_df(s.out))
  quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))
})

# 非与党寄りのシミュレーション
df_unemp <- data.frame(unem_norul = dat9_exp1$unem_norul,
                       unem_issue = dat9_exp1$unem_issue,
                       education = dat9_exp1$education,
                       gender = dat9_exp1$gender,
                       income = dat9_exp1$income,
                       age = dat9_exp1$age)
z_unem_norul <- zelig(unem_norul ~ unem_issue + age + gender + income + education, 
                      data = na.omit(df_unemp), model = "logit", cite = FALSE)
x_list <- list()
for (i in 1:5) {
  x_list[[i]] <- setx(z_unem_norul, unem_issue = i)
}
s.out_norul_list <- lapply(x_list, function(x) sim(z_unem_norul, x = x))
norulunem_par_list <- lapply(s.out_norul_list, function(s.out) {
  df_sim <- as.data.frame(zelig_qi_to_df(s.out))
  quantile(df_sim$expected_value, c(0.5, 0.025, 0.975))
})

# プロット用データ作成(被験者政策位置別)
data3 <- data.frame(rbind(do.call(rbind, rulunem_par_list), do.call(rbind, norulunem_par_list)))
colnames(data3) <- c("mean", "low", "up")
data3$情報の党派性 <- rep(c("与党寄り", "非与党寄り"), each = 5)
data3$被験者政策位置 <- rep(c("1pt", "2pt", "3pt", "4pt", "5pt"), times = 2)
data3$情報の党派性 <- factor(data3$情報の党派性, levels = c("与党寄り", "非与党寄り"))
data3$被験者政策位置 <- factor(data3$被験者政策位置, levels = c("1pt", "2pt", "3pt", "4pt", "5pt"))
data3 <- plot9_exp1hl(data3)
j3 <- plot9_exp1(data3, "被験者政策位置", "mean", "情報の党派性", "情報の党派性",
                           "被験者の政策位置", "", "政策位置")

# --------------------------
# 最終表示:3プロットを横並び
# --------------------------
windows(70, 25)
grid.arrange(j1, j2, j3, ncol = 3)

【実験9-1】データの検討:バランス・チェックと加重付与による追試)

バランス・チェック

バランス・チェックによれば、(1)失業・物価に関する実験のグループ間で、性別と年齢に関して統計的な有意差が認められる。また、(3)経済投票に関する実験のグループ間でも、年齢に関して統計的な有意差が認められる。群間で均質性が保たれていない可能性がある。一方で、本データでは、処置、党派性、結果変数の各変数がダミー変数であるため、

(1)失業・物価に関するグループ間でのバランス・チェック

dat9_exp1_bc1 <- na.omit(data.frame(group_unemp, age, gender, education, income_group, psu_rul))
tb_bc3 <- sumtable(dat9_exp1_bc1, group = "group_unemp", group.test = TRUE, title = "")

実験9-1のバランス・チェックの結果(失業・物価)

Table 3:
group_unemp
失業・非与党
失業・与党
物価・非与党
物価・与党
Variable N Mean SD N Mean SD N Mean SD N Mean SD Test
age 218 33 14 116 32 16 196 34 15 17 44 13 F=3.125**
gender 218 0.48 0.5 116 0.39 0.49 196 0.54 0.5 17 0.35 0.49 F=2.504*
education 218 3.2 0.88 116 3.1 0.92 196 3 0.87 17 3.2 1 F=2.487*
income_group 218 90 228 116 93 237 196 45 162 17 85 235 F=1.998
psu_rul 218 0.28 0.45 116 0.26 0.44 196 0.32 0.47 17 0.24 0.44 F=0.588
Statistical significance markers: * p<0.1; ** p<0.05; *** p<0.01

(2)外国人労働者・LGBTQグループ間でのバランス・チェック

実験9-1のバランス・チェックの結果(外国人労働者・LGBTQ)

Table 4:
group_foreign
LGBTQ・非与党
LGBTQ・与党
外国人・非与党
外国人・与党
Variable N Mean SD N Mean SD N Mean SD N Mean SD Test
age 546 35 15 193 35 14 228 36 14 14 35 15 F=0.981
gender 546 0.46 0.5 193 0.48 0.5 228 0.49 0.5 14 0.43 0.51 F=0.207
education 546 3.1 0.9 193 3.1 0.88 228 3 0.88 14 3.4 0.84 F=1.138
income_group 546 72 208 193 91 231 228 87 227 14 2.6 1.2 F=1.072
psu_rul 546 0.26 0.44 193 0.31 0.46 228 0.23 0.42 14 0.14 0.36 F=1.321
Statistical significance markers: * p<0.1; ** p<0.05; *** p<0.01

(3)経済投票グループ間でのバランス・チェック

実験9-1のバランス・チェックの結果(経済投票)

Table 5:
group_ev
経済投票・非与党
経済投票・与党
Variable N Mean SD N Mean SD Test
age 188 38 13 299 35 16 F=3.64*
gender 188 0.45 0.5 299 0.46 0.5 F=0.041
education 188 3.2 0.89 299 3.2 0.88 F=0.005
income_group 188 113 255 299 89 231 F=1.162
psu_rul 188 0.27 0.44 299 0.26 0.44 F=0.002
Statistical significance markers: * p<0.1; ** p<0.05; *** p<0.01

実験9-2・データの前処理

#--------------------------
# データの読み込み
#--------------------------
dat9_exp2 <- read.csv("bullock.csv", stringsAsFactors = FALSE)

#-------------
# 変数の設定
#-------------
#----処置関連変数の設定
dat9_exp2 <- dat9_exp2 %>%
  mutate(
    Q5.4_1_num = as.numeric(Q5.4_1),
    Q6.4_1_num = as.numeric(Q6.4_1),
    Q7.5_1_num = as.numeric(Q7.5_1)
  ) %>%
  mutate(
    group_correct = ifelse(!is.na(Q5.4_1_num) & Q5.4_1_num > 0, "正解報酬", NA_character_),
    correct_dum   = ifelse(!is.na(Q5.4_1_num) & Q5.4_1_num > 0, 1, 0),
    group_dk      = ifelse(!is.na(Q6.4_1_num) & Q6.4_1_num > 0, "DK報酬", NA_character_),
    dk_dum        = ifelse(!is.na(Q6.4_1_num) & Q6.4_1_num > 0, 1, 0),
    group_con     = ifelse(!is.na(Q7.5_1_num) & Q7.5_1_num > 0, "統制", NA_character_),
    control_dum   = ifelse(!is.na(Q7.5_1_num) & Q7.5_1_num > 0, 1, 0),
    # 複数のグループ変数のうち、最初に非欠損のものを group_quiz に設定
    group_quiz    = coalesce(group_correct, group_dk, group_con)
  )

#---- クイズ変数の作成
dat9_exp2 <- dat9_exp2 %>% 
  mutate(quiz1_1 = coalesce(rescale(Q5.4_1, na.rm = TRUE),
                            rescale(Q6.4_1, na.rm = TRUE),
                            rescale(Q7.5_1, na.rm = TRUE))) %>%
  mutate(quiz1_2 = coalesce(rescale(Q5.4_2, na.rm = TRUE),
                            rescale(Q6.4_2, na.rm = TRUE),
                            rescale(Q7.5_2, na.rm = TRUE))) %>%
  mutate(quiz2_1 = coalesce(rescale(Q5.5_1, na.rm = TRUE, to = c(1,0)),
                            rescale(Q6.5_1, na.rm = TRUE, to = c(1,0)),
                            rescale(Q7.6_1, na.rm = TRUE, to = c(1,0)))) %>%
  mutate(quiz2_2 = coalesce(rescale(Q5.5_2, na.rm = TRUE, to = c(1,0)),
                            rescale(Q6.5_2, na.rm = TRUE, to = c(1,0)),
                            rescale(Q7.6_2, na.rm = TRUE, to = c(1,0)))) %>%
  mutate(quiz3 = coalesce(rescale(Q5.6_1, na.rm = TRUE),
                          rescale(Q6.6_1, na.rm = TRUE),
                          rescale(Q7.7_1, na.rm = TRUE))) %>%
  mutate(quiz4_1 = coalesce(rescale(Q5.7_1, na.rm = TRUE),
                            rescale(Q6.7_1, na.rm = TRUE),
                            rescale(Q7.8_1, na.rm = TRUE))) %>%
  mutate(quiz4_2 = coalesce(rescale(Q5.7_2, na.rm = TRUE),
                            rescale(Q6.7_2, na.rm = TRUE),
                            rescale(Q7.8_2, na.rm = TRUE))) %>%
  mutate(quiz5_1 = coalesce(rescale(Q5.8_1, na.rm = TRUE),
                            rescale(Q6.8_1, na.rm = TRUE),
                            rescale(Q7.9_1, na.rm = TRUE))) %>%
  mutate(quiz5_2 = coalesce(rescale(Q5.8_2, na.rm = TRUE),
                            rescale(Q6.8_2, na.rm = TRUE),
                            rescale(Q7.9_2, na.rm = TRUE))) %>%
  mutate(quiz6_1 = coalesce(rescale(Q5.9_1, na.rm = TRUE),
                            rescale(Q6.9_1, na.rm = TRUE),
                            rescale(Q7.10_1, na.rm = TRUE))) %>%
  mutate(quiz6_2 = coalesce(rescale(Q5.9_2, na.rm = TRUE),
                            rescale(Q6.9_2, na.rm = TRUE),
                            rescale(Q7.10_2, na.rm = TRUE))) %>%
  mutate(quiz6_3 = coalesce(rescale(Q5.9_3, na.rm = TRUE),
                            rescale(Q6.9_3, na.rm = TRUE),
                            rescale(Q7.10_3, na.rm = TRUE))) %>%
  mutate(quiz7_1 = coalesce(rescale(Q5.10_1, na.rm = TRUE, to = c(1,0)),
                            rescale(Q6.10_1, na.rm = TRUE, to = c(1,0)),
                            rescale(Q7.11_1, na.rm = TRUE, to = c(1,0)))) %>%
  mutate(quiz8_1 = coalesce(rescale(Q5.11_1, na.rm = TRUE),
                            rescale(Q6.11_1, na.rm = TRUE),
                            rescale(Q7.12_1, na.rm = TRUE))) %>%
  mutate(quiz8_2 = coalesce(rescale(Q5.11_2, na.rm = TRUE),
                            rescale(Q6.11_2, na.rm = TRUE),
                            rescale(Q7.12_2, na.rm = TRUE))) %>%
  mutate(quiz8_3 = coalesce(rescale(Q5.11_3, na.rm = TRUE),
                            rescale(Q6.11_3, na.rm = TRUE),
                            rescale(Q7.12_3, na.rm = TRUE)))

#クイズ・スコアの作成
dat9_exp2 <- dat9_exp2 %>% 
  mutate(quiz_score = (quiz1_1 + quiz1_2 + quiz2_1 + quiz2_2 + quiz3 +
                       quiz4_1 + quiz4_2 + quiz5_1 + quiz5_2 +
                       quiz6_1 + quiz6_2 + quiz6_3 + quiz7_1 +
                       quiz8_1 + quiz8_2 + quiz8_3) / 16)

#---- 政党支持変数の設定
dat9_exp2 <- dat9_exp2 %>% 
  mutate(psu = case_when(
    Q2.7 %in% c(1, 3) ~ "与党派",
    Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ "野党派",
    Q2.7 == 10 ~ "無党派",
    Q2.7 %in% c(11, 12) ~ NA_character_,
    TRUE ~ NA_character_
  ))


#---- (3) party support dummy: ruling dummy の作成
#与党派
dat9_exp2 <- dat9_exp2 %>% 
  mutate(psu_rul = case_when(
    Q2.7 %in% c(1, 3) ~ 1,
    Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ 0,
    Q2.7 == 10 ~ 0,
    Q2.7 %in% c(11, 12) ~ NA_real_,
    TRUE ~ NA_real_
  ))

#野党派
dat9_exp2 <- dat9_exp2 %>% 
  mutate(psu_op = case_when(
    Q2.7 %in% c(1, 3) ~ 0,
    Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ 1,
    Q2.7 == 10 ~ 0,
    Q2.7 %in% c(11, 12) ~ NA_real_,
    TRUE ~ NA_real_
  ))

#無党派
dat9_exp2 <- dat9_exp2 %>% 
  mutate(psu_indep = case_when(
    Q2.7 %in% c(1, 3) ~ 0,
    Q2.7 %in% c(4, 2, 5, 6, 7, 8, 9, 14) ~ 0,
    Q2.7 == 10 ~ 1,
    Q2.7 %in% c(11, 12) ~ NA_real_,
    TRUE ~ NA_real_
  ))


#----共変量の設定
dat9_exp2 <- dat9_exp2 %>% 
  mutate(age = Q2.2) %>%
  mutate(income = Q3.1_1) %>%
  mutate(gender = case_when(
    Q2.1 == 1 ~ 1,
    Q2.1 == 2 ~ 0,
    Q2.1 %in% c(3,4) ~ NA_real_
  )) %>%
  mutate(education = case_when(
    Q2.4 < 3.01 ~ 0,
    Q2.4 > 3.99 ~ 1,
    Q2.4 %in% c(6,7) ~ NA_real_
  ))

#----2つ目の政党支持変数
# 与党派
dat9_exp2 <- dat9_exp2 %>% 
  mutate(ruling_dummy = case_when(
    psu == "与党派" ~ 1,
    psu %in% c("野党派", "無党派") ~ 0,
    TRUE ~ NA_real_
  ))

# 野党派
dat9_exp2 <- dat9_exp2 %>% 
  mutate(opposite_dummy = case_when(
    psu == "野党派" ~ 1,
    psu %in% c("与党派", "無党派") ~ 0,
    TRUE ~ NA_real_
  ))

# 無党派
dat9_exp2 <- dat9_exp2 %>% 
  mutate(indep_dummy = case_when(
    psu == "無党派" ~ 1,
    psu %in% c("与党派", "野党派") ~ 0,
    TRUE ~ NA_real_
  ))

【補足】党派性解答スコアの党派別分布

本文中では示さなかった、党派性解答スコアの党派別の分布は次の通りである。

#----------------
# 関数の読み込み
#----------------
source("plot9_exp2dens2.R")

#--------------
# データの設定
#--------------
df <- dat9_exp2

#--------------------------------------------------
# 各クイズ変数の分布に関するプロットの作成
#--------------------------------------------------
q1_1 <- plot9_exp2dens2("quiz1_1", "岸田政権発足時・日経平均")
q1_2 <- plot9_exp2dens2("quiz1_2", "2022/9/25・日経平均")
q2_1 <- plot9_exp2dens2("quiz2_1", "岸田政権発足時・CPI")
q2_2 <- plot9_exp2dens2("quiz2_2", "2022/9/25・CPI")
q3   <- plot9_exp2dens2("quiz3",   "防衛費対GDP比")
q4_1 <- plot9_exp2dens2("quiz4_1", "2021衆選・自民得票率")
q4_2 <- plot9_exp2dens2("quiz4_2", "現在・自民議席率")
q5_1 <- plot9_exp2dens2("quiz5_1", "自民予測得票率")
q5_2 <- plot9_exp2dens2("quiz5_2", "自民予測議席率")
q6_1 <- plot9_exp2dens2("quiz6_1", "社会保障費割合")
q6_2 <- plot9_exp2dens2("quiz6_2", "公共事業費割合")
q6_3 <- plot9_exp2dens2("quiz6_3", "防衛費割合")
q7_1 <- plot9_exp2dens2("quiz7_1", "外国人労働者割合")
q8_1 <- plot9_exp2dens2("quiz8_1", "内閣支持率", ylab_text = "")
q8_2 <- plot9_exp2dens2("quiz8_2", "景気評価", ylab_text = "")
q8_3 <- plot9_exp2dens2("quiz8_3", "暮らし向き評価", ylab_text = "")

# プロットを2列に並べて表示
grid.arrange(q1_1, q1_2, q2_1, q2_2, q3, q4_1, q4_2, q5_1, q5_2, 
             q6_1, q6_2, q6_3, q7_1, q8_1, q8_2, q8_3, ncol = 2)

図9-9:【実験9─2】処置,党派性,処置と党派性のもとでの党派性解答スコアの平均値の差のプロット)

#----------------
# 関数の読み込み
#----------------
source("plot9_exp2bar1.R")
source("plot9_exp2bar2.R")

#---------------------------------------
# 処置別の平均値・標準誤差プロット (j1)
#---------------------------------------
#----データ整形
df_quiz <- dat9_exp2 %>% 
  select(quiz_score, group_quiz) %>% 
  na.omit() %>%
  mutate(group_quiz = factor(group_quiz, levels = c("正解報酬", "DK報酬", "統制")))

#----比較対象の組み合わせ
my_comparisons <- list(c("正解報酬", "統制"), c("DK報酬", "統制"))


#---- プロット(p1)の作成
j1 <- plot9_exp2bar1(df_quiz, "group_quiz", "処置", my_comparisons)


#---------------------------------------
# 党派別の平均値・標準誤差プロット (j2)
#---------------------------------------
#----データ成形
df_psu <- dat9_exp2 %>% 
  select(quiz_score, psu) %>% 
  na.omit() %>%
  mutate(psu = factor(psu, levels = c("与党派", "野党派", "無党派")))

#----比較対象の組み合わせ
my_comparisons_psu <- list(c("与党派", "無党派"), c("野党派", "無党派"), c("与党派", "野党派"))

#---- プロット(p2)の作成
j2 <- plot9_exp2bar1(df_psu, "psu", "党派性", my_comparisons_psu)

#---------------------------------------------
# 処置・党派別の平均値・標準誤差プロット (j3)
#---------------------------------------------
#---- データの成形
df_gpsu <- dat9_exp2 %>% 
  select(quiz_score, group_quiz, psu) %>% 
  na.omit() %>%
  mutate(group_psu = paste(group_quiz, psu, sep = "-"))

df_summary2 <- df_gpsu %>% 
  group_by(group_quiz, psu, group_psu) %>% 
  summarise(mean_quiz_score = mean(quiz_score),
            se_quiz_score = sd(quiz_score) / sqrt(n()),
            .groups = "drop")

#----比較対象の組み合わせ
my_comparisons2 <- list(c("DK報酬-無党派", "統制-無党派"), c("正解報酬-与党派", "統制-与党派"))

#---- プロット(p3)の作成
j3 <- plo9_exp2bar2(df_summary2, "group_psu", "psu", "処置×党派", my_comparisons2)

#----------------
# プロットの表示
#----------------
grid.arrange(j1, j2, j3, ncol = 2)

【補足】推定方法の説明

実験9-2のデータをどのように分析するか?

推定方法は、Guay & Johnston (2021)に従い、正答の確率に対して党派性、イデオロギー、政策位置が与える効果を測るものである。基盤となる推定モデルは下記の通りである;

\[\begin{eqnarray} ln((y_{correct})/(1-y_{correct} ))=\beta_0+\beta_1x_{partisan}+\beta_2 x_{sex}+\beta_3x_{age}+\beta_4 x_{education}+\beta_5 x_{income}. \end{eqnarray}\tag{8}\]

(8)式をもとに、\(y_{correct}\)は与党派寄り/非与党派寄りの根拠提示に対して正答するか否かを表すダミー変数である。\(\beta_1x_{partisan}\)は被験者自身が与党派か非与党派かを表すダミー変数である。(8)式にもとづいて、\(\beta_1 x_{partisan=1}\)\(\beta_1x_{partisan=0}\)の場合での正答確率を計算しプロットする。また、\(\beta_1x_{partisan}\)が、イデオロギー\(\beta_1 x_{ideology}\)、政策位置\(\beta_1 x_{issue}\)の場合の推定モデルも定め、それらのシミュレーションも行う。

図9-10:【実験9─2】党派性解答スコアの党派性差異のプロット

#----------------
# 関数の読み込み
#----------------
source("plot9_exp2sim.R")

#--------------
# データの設定
#--------------
df_par <- dat9_exp2 %>% dplyr::select(quiz_score, age, education, gender, income, 
                             psu_rul, psu_op, psu_indep) %>%
                             na.omit()

#-----------------------
# シミュレーションの実行
#------------------------
#----共変量の設定
cov_vals <- list(income = 503, gender = 0, education = 4, age = 32)


#----シミュレーション実施
sim_rul_fd   <- plot9_exp2sim("psu_rul", df_par, cov_vals)
sim_op_fd    <- plot9_exp2sim("psu_op",  df_par, cov_vals)
sim_indep_fd <- plot9_exp2sim("psu_indep", df_par, cov_vals)


#---------------------------------
# 推定結果のデータフレームへの成形
#---------------------------------
dfquiz_party <- data.frame(
  党派 = c("与党派", "野党派", "無党派"),
  coef = c(sim_rul_fd[1], sim_op_fd[1], sim_indep_fd[1]),
  low  = c(sim_rul_fd[2], sim_op_fd[2], sim_indep_fd[2]),
  up   = c(sim_rul_fd[3], sim_op_fd[3], sim_indep_fd[3])
)

dfquiz_party <- dfquiz_party %>%
  mutate(党派 = factor(党派, levels = c("与党派", "野党派", "無党派")),
         significance = ifelse(low > 0 | up < 0, "significant", "not significant"))

#----------------
# プロットの作成
#----------------
ggplot(data = dfquiz_party, aes(x = 党派, y = coef, ymin = low, ymax = up)) +
  geom_hline(yintercept = 0, color = "black", size = 0.5) +
  # 有意な場合に背景ハイライト
  geom_rect(data = subset(dfquiz_party, significance == "significant"),
            aes(xmin = as.numeric(党派) - 0.15, xmax = as.numeric(党派) + 0.15,
                ymin = low, ymax = up),
            fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
  geom_errorbar(width = 0.2, size = 0.2, aes(color = significance)) +
  geom_point(size = 3, shape = 21, aes(fill = significance), color = "black") +
  geom_text(aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ", ", round(up, 2), "]")),
            vjust = -1, size = 3.5, color = "black") +
  scale_y_continuous(limits = c(-0.1, 0.1), breaks = seq(-0.1, 0.1, by = 0.025)) +
  coord_cartesian(ylim = c(-0.1, 0.1)) +
  xlab("党派") + ylab("党派別での党派性解答スコア差") +
  scale_fill_manual(values = c("significant" = "grey", "not significant" = "white")) +
  scale_color_manual(values = c("significant" = "grey", "not significant" = "black")) +
  theme_bw() +
  theme(legend.position = "none")

図9-11:【実験9─2】処置のもとでの党派性差異

#----------------
# 関数の読み込み
#----------------
source("plot9_exp2sim2.R")

df_par <- dat9_exp2 %>% 
  select(quiz_score, age, education, gender, income, 
         psu_rul, psu_op, psu_indep, control_dum, dk_dum, correct_dum) %>% 
  na.omit()

cov_vals <- list(income = 503, gender = 0, education = 4, age = 32)



#-----------------------
# シミュレーションの実行
#------------------------
#---- 正解刺激 
fd_rul_corr   <- plot9_exp2sim2(data=df_par, outcome="quiz_score",
                              base_var="psu_rul", treat_var="correct_dum")

fd_op_corr    <- plot9_exp2sim2(data=df_par, outcome="quiz_score",
                              base_var="psu_op", treat_var="correct_dum")

fd_indep_corr <- plot9_exp2sim2(data=df_par, outcome="quiz_score",
                              base_var="psu_indep", treat_var="correct_dum")

#---- DK刺激
fd_rul_dk   <- plot9_exp2sim2(data=df_par, outcome="quiz_score",
                            base_var="psu_rul", treat_var="dk_dum")

fd_op_dk    <- plot9_exp2sim2(data=df_par, outcome="quiz_score",
                            base_var="psu_op", treat_var="dk_dum")

fd_indep_dk <- plot9_exp2sim2(data=df_par, outcome="quiz_score",
                            base_var="psu_indep", treat_var="dk_dum")


#---------------------------------
# 推定結果のデータフレームへの成形
#---------------------------------
df_quiz_corr <- data.frame(
  処置種類 = "正解報酬",
  党派     = c("与党派","野党派","無党派"),
  coef     = c(fd_rul_corr[1], fd_op_corr[1], fd_indep_corr[1]),
  low      = c(fd_rul_corr[2], fd_op_corr[2], fd_indep_corr[2]),
  up       = c(fd_rul_corr[3], fd_op_corr[3], fd_indep_corr[3])
)

df_quiz_dk <- data.frame(
  処置種類 = "DK報酬",
  党派     = c("与党派","野党派","無党派"),
  coef     = c(fd_rul_dk[1], fd_op_dk[1], fd_indep_dk[1]),
  low      = c(fd_rul_dk[2], fd_op_dk[2], fd_indep_dk[2]),
  up       = c(fd_rul_dk[3], fd_op_dk[3], fd_indep_dk[3])
)

df_quiz <- rbind(df_quiz_corr, df_quiz_dk)

df_quiz <- df_quiz %>%
  mutate(
    党派 = factor(党派, levels = c("与党派","野党派","無党派")),
    処置種類 = factor(処置種類, levels=c("正解報酬","DK報酬"))
  )

df_quiz <- df_quiz %>%
  mutate(highlight = (low>0 & up>0) | (low<0 & up<0))


#-----------------
# プロットの作成
#-----------------
pd <- position_dodge(0.2)

ggplot(df_quiz, aes(x = 党派, y = coef, ymin = low, ymax = up,
                         linetype = 処置種類, group = 処置種類, fill=処置種類)) +
  geom_hline(yintercept=0, color="black", size=0.5) +

  geom_rect(
    data = subset(df_quiz, highlight==TRUE),
    aes(xmin=as.numeric(党派)-0.15, xmax=as.numeric(党派)+0.15, ymin=low, ymax=up),
    fill="grey90", alpha=0.5, inherit.aes=FALSE, position=pd
  ) +

  geom_errorbar(size=0.2, width=0.1, linetype=1, color="black", position=pd) +
  geom_point(size=3, shape=21, fill="white", position=pd) +
  geom_line(position=pd) +

  geom_text(
    data = subset(df_quiz, highlight==TRUE),
    aes(label=paste0(round(coef,2),"\n[",round(low,2),",",round(up,2),"]")),
    vjust=-1, size=3.5, color="black", position=pd
  ) +
  
  scale_y_continuous(
    limits=c(-0.1,0.1),
    breaks=seq(-0.1,0.1,by=0.025)
  ) +
  coord_cartesian(ylim=c(-0.1,0.1)) +
  
  xlab("党派") + ylab("処置ごとでの党派性解答スコア差") +
  
  theme_bw() +
  theme(
    legend.position = c(0.1, 0.1),
    legend.key.size = unit(0.3,"cm"),
    plot.title      = element_text(face="bold")
  )

【補足】図9-11のOLS推定の結果

以下では、シミュレーションの基盤となるOLS推定の結果を報告する。表内のアスタリスク(*)は、5%水準で統計的に有意であることを表す。

#----------------
# 関数の読み込み
#----------------
source("plot9_exp2tab.R")

#--------------
# データの設定
#--------------
df_par <- dat9_exp2 %>% 
  select(quiz_score, correct_dum, dk_dum, psu_rul, psu_op, age, gender, education, income) %>% 
  na.omit()

#--------------------------
# 交互作用なしモデルの推定
#--------------------------
model_main <- lm(quiz_score ~ correct_dum + dk_dum + psu_rul + psu_op + age + gender + 
                   education + income, 
                 data = df_par)

#--------------------------
# 交互作用ありモデルの推定
#--------------------------
model_inter <- lm(quiz_score ~ correct_dum + dk_dum + psu_rul + psu_op + age + gender + 
                    education + income +
                    correct_dum:psu_rul + correct_dum:psu_op + dk_dum:psu_rul + dk_dum:psu_op, 
                  data = df_par)


var_order_main <- c("correct_dum", "dk_dum", "psu_rul", "psu_op", "age", "gender", "education", "income")
var_order_inter <- c(var_order_main, "correct_dum:psu_rul", "correct_dum:psu_op", "dk_dum:psu_rul", "dk_dum:psu_op")


term_labels <- c(
  "correct_dum"         = "正解刺激",
  "dk_dum"              = "DK刺激",
  "psu_rul"             = "与党派",
  "psu_op"              = "野党支持",
  "age"                 = "年齢",
  "gender"              = "性別",
  "education"           = "教育歴",
  "income"              = "所得",
  "correct_dum:psu_rul" = "正解刺激×与党派",
  "correct_dum:psu_op"  = "正解刺激×野党支持",
  "dk_dum:psu_rul"      = "DK刺激×与党派",
  "dk_dum:psu_op"       = "DK刺激×野党支持"
)


#--------------- 
# 推定結果を成形
#---------------
res_main  <- plot9_exp2tab(model_main, var_order_main, "Main")
res_inter <- plot9_exp2tab(model_inter, var_order_inter, "Inter")

renamet <- function(df, term_labels) {
  df %>%
    mutate(term = ifelse(term %in% names(term_labels), term_labels[term], term))
}

res_main  <- renamet(res_main, term_labels)
res_inter <- renamet(res_inter, term_labels)


final_df <- full_join(res_main, res_inter, by = "term")

final_df <- final_df %>%
  arrange(factor(term, levels = c(unname(term_labels[var_order_main]), 
                                    unname(term_labels[setdiff(var_order_inter, 
                                                               var_order_main)]),
                                    "モデルの要約")))

colnames(final_df)[2:3] <- c("交差項無", "交差項有")

#------------
# 結果を表化
#------------
tb_ols <- final_df %>%
  kable("html", align = "c", row.names = FALSE) %>%
  kable_styling(full_width = FALSE)

図9-12:【実験9─2】最小二乗法による経済評価の解答値と内閣支持率の解答値の関係の分析(党派性ごとのサンプル)

#----------------------------
# データの読み込みと変数作成
#----------------------------
dat9_exp2 <- dat9_exp2 %>%
  mutate(
    cabapp = coalesce(Q5.11_1, Q6.11_1, Q7.12_1),
    keiki = coalesce(Q5.11_2, Q6.11_2, Q7.12_2),
    kurashimuki = coalesce(Q5.11_3, Q6.11_3, Q7.12_3)
  )

data <- dat9_exp2 %>% 
  select(cabapp, keiki, kurashimuki, psu_rul, psu_op, psu_indep,
         age, education, income, gender) %>% 
  na.omit()

#-------------------------
# 各党派サンプルのOLS推定
#-------------------------
model_rul   <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_rul == 1))
model_op    <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_op == 1))
model_indep <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_indep == 1))

#----------------
# 推定結果の成形
#----------------
maketib <- function(model, label) {
  tidy(model) %>% mutate(model = label)
}

df_rul   <- maketib(model_rul, "与党派サンプル")
df_op    <- maketib(model_op, "野党派サンプル")
df_indep <- maketib(model_indep, "無党派サンプル")

all_df <- bind_rows(df_rul, df_op, df_indep)

filtered_df <- all_df %>% 
  filter(term %in% c("psu_rul", "psu_op", "psu_indep", "keiki", "kurashimuki"))

filtered_df <- filtered_df %>%
  mutate(conf.low = estimate - 1.96 * std.error,
         conf.high = estimate + 1.96 * std.error)

filtered_df <- filtered_df %>%
  mutate(term_jp = case_when(
    term == "psu_rul"    ~ "与党支持",
    term == "psu_op"     ~ "野党支持",
    term == "psu_indep"  ~ "無党派",
    term == "keiki"      ~ "景気",
    term == "kurashimuki"~ "暮らし向き",
    TRUE ~ term
  ))

filtered_df <- filtered_df %>%
  mutate(model = factor(model, levels = c("与党派サンプル", "野党派サンプル", "無党派サンプル")))

filtered_df <- filtered_df %>%
  mutate(highlight = (conf.low > 0 & conf.high > 0) | (conf.low < 0 & conf.high < 0))

#----------------
# プロットの作成
#----------------
pd <- position_dodge(0.2)
j1 <- ggplot(filtered_df, aes(x = term_jp, y = estimate)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "black", size = 0.5) +
  geom_rect(data = subset(filtered_df, highlight == TRUE),
            aes(xmin = as.numeric(factor(term_jp)) - 0.4,
                xmax = as.numeric(factor(term_jp)) + 0.4,
                ymin = conf.low, ymax = conf.high),
            fill = "grey90", alpha = 0.5, inherit.aes = FALSE, position = pd) +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2, color = "black", position = pd) +
  geom_point(size = 3, shape = 21, fill = "white", color = "black", position = pd) +
  geom_text(data = subset(filtered_df, highlight == TRUE),
            aes(label = paste0(round(estimate, 2), "\n[", round(conf.low, 2), ", ", round(conf.high, 2), "]")),
            hjust = -0.3, size = 3.5, color = "black", position = pd) +
  facet_wrap(~ model, ncol = 3) +
  xlab("独立変数") + ylab("係数") +
  ggtitle("OLS推定結果(内閣支持率解答)") +
  theme_bw() +
  theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1),
        text = element_text(family = "jpfont"))

【補足】図9-12のOLS推定結果

#----------------
# 関数の読み込み
#----------------
source("plot9_exp2tab2.R")

#----------------------------
# データの読み込みと変数作成 
#----------------------------
dat9_exp2 <- dat9_exp2 %>%
  mutate(
    cabapp      = coalesce(Q5.11_1, Q6.11_1, Q7.12_1),
    keiki       = coalesce(Q5.11_2, Q6.11_2, Q7.12_2),
    kurashimuki = coalesce(Q5.11_3, Q6.11_3, Q7.12_3)
  )

df_data <- dat9_exp2 %>%
  select(cabapp, keiki, kurashimuki, psu_rul, psu_op, psu_indep,
         age, education, income, gender) %>%
  na.omit()

#-----------------------------
# 各党派サンプルごとのOLS推定 
#-----------------------------
# 与党派サンプル
model_rul <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender,
                data = subset(df_data, psu_rul == 1))

# 野党派サンプル
model_op <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender,
               data = subset(df_data, psu_op == 1))

# 無党派サンプル
model_indep <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender,
                  data = subset(df_data, psu_indep == 1))


#--------------- 
# 推定結果を成形
#---------------
var_order <- c("keiki", "kurashimuki", "age", "education", "income", "gender")

res_rul   <- plot9_exp2tab2(model_rul,   "与党派サンプル", var_order)
res_op    <- plot9_exp2tab2(model_op,    "野党派サンプル", var_order)
res_indep <- plot9_exp2tab2(model_indep, "無党派サンプル", var_order)


term_labels <- c(
  "keiki"        = "景気",
  "kurashimuki"  = "暮らし向き",
  "age"          = "年齢",
  "education"    = "教育歴",
  "income"       = "所得",
  "gender"       = "性別"
)

renamet2 <- function(df, dict) {
  df %>%
    mutate(term = ifelse(term %in% names(dict), dict[term], term))
}

res_rul   <- renamet2(res_rul,   term_labels)
res_op    <- renamet2(res_op,    term_labels)
res_indep <- renamet2(res_indep, term_labels)


final_df <- res_rul %>%
  full_join(res_op,    by="term") %>%
  full_join(res_indep, by="term")

final_df <- final_df %>%
  rename(`独立変数` = term) %>%
  arrange(
    factor(
      `独立変数`, 
      levels = c(unname(term_labels[var_order]), "モデル要約")
    )
  )

colnames(final_df)[2:4] <- c("与党派サンプル", "野党派サンプル", "無党派サンプル")

#------------
# 結果を表化
#------------
tb_ols <- final_df %>%
  kable("html", align = "c", row.names = FALSE) %>%
  kable_styling(full_width = FALSE)

OLS推定の結果(内閣支持率: 党派サンプル別)

独立変数 与党派サンプル 野党派サンプル 無党派サンプル
景気 0.288*** (0.035) 0.227*** (0.033) 0.307*** (0.030)
暮らし向き 0.184*** (0.036) 0.145*** (0.033) 0.069*** (0.029)
年齢 0.008 (0.026) 0.073*** (0.024) 0.065*** (0.022)
教育歴 0.297 (0.673) 1.561*** (0.639) 1.608*** (0.532)
所得 -0.000 (0.001) 0.001*** (0.001) -0.002*** (0.001)
性別 1.828*** (0.661) -1.019 (0.644) 0.436 (0.485)
モデル要約 n=885, R²=0.321, F=69.254 n=806, R²=0.298, F=56.528 n=1230, R²=0.269, F=75.071

図9-13:【実験9-2】最小二乗法による経済評価の解答値と内閣支持率の解答値の関係の分析(処置の効果)

#--------------
# データの設定
#--------------
dat9_exp2 <- dat9_exp2 %>%
  mutate(
    cabapp      = coalesce(Q5.11_1, Q6.11_1, Q7.12_1),
    keiki       = coalesce(Q5.11_2, Q6.11_2, Q7.12_2),
    kurashimuki = coalesce(Q5.11_3, Q6.11_3, Q7.12_3),
    
    処置 = case_when(
      correct_dum == 1 ~ "正解処置",
      dk_dum == 1      ~ "DK処置",
      TRUE             ~ "統制群"
    )
  ) 


#------------------
# 推定モデルの設定
#------------------

model_specs <- list(
  list(
    name    = "result_regrul1",
    formula = "cabapp ~ psu_rul + keiki + kurashimuki + age + education + income + gender",
    subset  = "control_dum == 1",   
    model   = "与党派",
    treat   = "統制群"
  ),
  list(
    name    = "result_regop1",
    formula = "cabapp ~ psu_op + keiki + kurashimuki + age + education + income + gender",
    subset  = "control_dum == 1",
    model   = "野党派",
    treat   = "統制群"
  ),
  list(
    name    = "result_regindep1",
    formula = "cabapp ~ psu_indep + keiki + kurashimuki + age + education + income + gender",
    subset  = "control_dum == 1",
    model   = "無党派",
    treat   = "統制群"
  ),
  list(
    name    = "result_regrul2",
    formula = "cabapp ~ psu_rul + keiki + kurashimuki + age + education + income + gender",
    subset  = "correct_dum == 1",
    model   = "与党派",
    treat   = "正解処置"
  ),
  list(
    name    = "result_regop2",
    formula = "cabapp ~ psu_op + keiki + kurashimuki + age + education + income + gender",
    subset  = "correct_dum == 1",
    model   = "野党派",
    treat   = "正解処置"
  ),
  list(
    name    = "result_regindep2",
    formula = "cabapp ~ psu_indep + keiki + kurashimuki + age + education + income + gender",
    subset  = "correct_dum == 1",
    model   = "無党派",
    treat   = "正解処置"
  ),
  list(
    name    = "result_regrul3",
    formula = "cabapp ~ psu_rul + keiki + kurashimuki + age + education + income + gender",
    subset  = "dk_dum == 1",
    model   = "与党派",
    treat   = "DK処置"
  ),
  list(
    name    = "result_regop3",
    formula = "cabapp ~ psu_op + keiki + kurashimuki + age + education + income + gender",
    subset  = "dk_dum == 1",
    model   = "野党派",
    treat   = "DK処置"
  ),
  list(
    name    = "result_regindep3",
    formula = "cabapp ~ psu_indep + keiki + kurashimuki + age + education + income + gender",
    subset  = "dk_dum == 1",
    model   = "無党派",
    treat   = "DK処置"
  )
)

#----------------------------
# 推定の実行と推定結果の成形
#----------------------------
all_df_list <- list()
for (spec in model_specs) {
  subset_idx <- with(data, eval(parse(text = spec$subset)))
  
  mod <- lm(as.formula(spec$formula), data = data[subset_idx,])
  
  df_tidy <- tidy(mod) %>%
    mutate(model = spec$model, 処置 = spec$treat)
  
  all_df_list[[spec$name]] <- df_tidy
}

all_df <- dplyr::bind_rows(all_df_list)

filtered_df <- all_df %>%
  filter(term %in% c("psu_rul","psu_op","psu_indep","keiki","kurashimuki"))

filtered_df <- filtered_df %>%
  mutate(term_japanese = dplyr::case_when(
    term=="psu_rul"     ~ "与党支持",
    term=="psu_op"      ~ "野党支持",
    term=="psu_indep"   ~ "無党派",
    term=="keiki"       ~ "景気",
    term=="kurashimuki" ~ "暮らし向き",
    TRUE ~ term
  ))

filtered_df$model <- factor(filtered_df$model, levels=c("与党派","野党派","無党派"))
filtered_df$処置  <- factor(filtered_df$処置, levels=c("正解処置","DK処置","統制群"))
filtered_df$term_japanese <- factor(filtered_df$term_japanese,
  levels=c("与党支持","野党支持","無党派","景気","暮らし向き"))

assign("filtered_df_9_13", filtered_df, envir=.GlobalEnv)

filtered_df <- filtered_df_9_13 %>%
  mutate(
    conf.low = estimate - 1.96*std.error,
    conf.high= estimate + 1.96*std.error,
    highlight= ((conf.low>0 & conf.high>0) | (conf.low<0 & conf.high<0))
  )

#----------------
# プロットの作成
#----------------

pd <- position_dodge(width=0.5)
ggplot(filtered_df, aes(x=term_japanese, y=estimate, group=処置)) +
  geom_tile(
    data = subset(filtered_df, highlight == TRUE),
    aes(width=0.2, height=std.error*2),
    fill="grey90", alpha=0.5, position=pd
  ) +
  geom_point(aes(shape=処置, size=処置), color="black", position=pd) +
  geom_errorbar(aes(ymin=conf.low, ymax=conf.high), width=0.2, color="black", position=pd) +
  
  geom_text_repel(
    data=subset(filtered_df, highlight==TRUE),
    aes(label=paste0(round(estimate,2), "\n[",round(conf.low,2),",",round(conf.high,2),"]")),
    size=3.5, color="black", force=1.5, position=pd
  ) +
  geom_hline(yintercept=0, linetype="dashed") +
    theme_bw() +
  xlab("右辺変数") + ylab("係数") +
  labs(title="OLS推定結果(左辺変数:内閣支持率解答)") +
  scale_shape_manual(values=c("正解処置"=15, "DK処置"=17, "統制群"=16)) +
  scale_size_manual(values=c("正解処置"=2,  "DK処置"=2,  "統制群"=2)) +
  theme(legend.position="right",
        axis.text.x=element_text(angle=45, hjust=1))

【補足】図9-13のOLS推定結果

#-----------------
# 関数の読み込み
#-----------------
source("plot9_exp2tab3.R")

#-----------------
# データの設定
#-----------------
dat9_exp2 <- dat9_exp2 %>%
  mutate(
    cabapp      = coalesce(Q5.11_1, Q6.11_1, Q7.12_1),
    keiki       = coalesce(Q5.11_2, Q6.11_2, Q7.12_2),
    kurashimuki = coalesce(Q5.11_3, Q6.11_3, Q7.12_3),
    
    処置 = case_when(
      correct_dum == 1 ~ "正解処置",
      dk_dum == 1      ~ "DK処置",
      TRUE             ~ "統制群"
    )
  ) 

dat9_exp2 <- dat9_exp2 %>%
  dplyr::select(cabapp, keiki, kurashimuki,
         psu_rul, psu_op, psu_indep,
         age, education, income, gender,
         correct_dum, dk_dum, control_dum, 処置) %>%
  na.omit()


#---------------------
# 各処置ごとのOLS推定 
#---------------------
var_order <- c("psu_rul", "psu_op", "keiki", "kurashimuki", "age", "gender", "education", "income")
var_labels <- c("与党支持", "野党支持", "景気", "暮らし向き", "年齢", "性別", "教育歴", "所得")


res_correct <- plot9_exp2tab3("正解処置")
res_dk      <- plot9_exp2tab3("DK処置")
res_control <- plot9_exp2tab3("統制群")


#--------------- 
# 推定結果を成形
#---------------
final_table <- res_correct %>%
  rename(`正解処置` = coef_str) %>%
  full_join(res_dk %>% rename(`DK処置` = coef_str), by = "term_jp") %>%
  full_join(res_control %>% rename(`統制群` = coef_str), by = "term_jp") %>%
  rename(`独立変数` = term_jp) %>%
  # 並べ替え: var_labels + "モデル要約" (最下行)
  arrange(factor(`独立変数`, levels = c(var_labels, "モデル要約")))

#------------ 
# 結果を表化
#------------
tb_ols <- final_table %>%
  kable("html", 
        align = "c", row.names = FALSE) %>%
  kable_styling(full_width = FALSE)

OLS推定の結果(内閣支持率: 処置別)

独立変数 与党派サンプル 野党派サンプル 無党派サンプル
景気 0.288*** (0.035) 0.227*** (0.033) 0.307*** (0.030)
暮らし向き 0.184*** (0.036) 0.145*** (0.033) 0.069*** (0.029)
年齢 0.008 (0.026) 0.073*** (0.024) 0.065*** (0.022)
教育歴 0.297 (0.673) 1.561*** (0.639) 1.608*** (0.532)
所得 -0.000 (0.001) 0.001*** (0.001) -0.002*** (0.001)
性別 1.828*** (0.661) -1.019 (0.644) 0.436 (0.485)
モデル要約 n=885, R²=0.321, F=69.254 n=806, R²=0.298, F=56.528 n=1230, R²=0.269, F=75.071

【実験9-2】データの検討:バランス・チェックと加重付与による追試)

バランス・チェック

バランス・チェックによれば、処置群、及び統制群との間で、性別、年齢、教育歴、所得に関して統計的な有意差が認められる。群間で均質性が保たれていない可能性があることから、一般的な傾向スコア、エントロピー・バランシングによって、データを重みづけした推定結果を示す。

dat9_exp2_bc <- dat9_exp2 %>%
  dplyr::select(処置, age, gender, education, income, psu_rul)
tb_bc6 <- sumtable(dat9_exp2_bc, group = "処置", group.test = TRUE, title = "")

実験9-2のバランス・チェックの結果

Table 6:
処置
DK処置
正解処置
統制群
Variable N Mean SD N Mean SD N Mean SD Test
age 394 34 12 644 32 12 2074 32 12 F=5.31***
gender 393 0.24 0.43 637 0.3 0.46 2054 0.37 0.48 F=13.67***
education 364 0.73 0.44 587 0.75 0.43 1969 0.7 0.46 F=4.267**
income 395 642 473 644 612 451 2077 584 443 F=3.173**
psu_rul 387 0.35 0.48 633 0.3 0.46 2003 0.29 0.45 F=2.531*
Statistical significance markers: * p<0.1; ** p<0.05; *** p<0.01

傾向スコアによるデータへの重みづけ

傾向スコアによるデータの重みづけ、そして以下に示すエントロピー・バランシングによる加重付与後のデータによる分析からは、本文とはかなり異なる結果が得られている。また加重付与した場合の2つのデータにおいても、共通する傾向が認められているわけではない。本文も含めた3つの異なる結果は解釈が難しいものとなっている。

#------------------------------
# 加重算出のためのデータの設定
#------------------------------
dat9_exp2_weight <- dat9_exp2 %>% 
  dplyr::select(
    quiz_score, psu_rul, psu_op, psu_indep,
    age, income, gender, education,
    cabapp, keiki, kurashimuki,
    処置, correct_dum, dk_dum, control_dum, psu
  ) %>% 
  na.omit()

#------------------------------
# 傾向スコアの算出と加重算出
#------------------------------
W.out <- weightit(
  as.factor(処置) ~ age + gender + income + education + psu_rul,
  data = dat9_exp2_weight,
  method = "ps",
  estimand = "ATE",
  family = "multinomial"
)

dat9_exp2_weight <- dat9_exp2_weight %>%
  mutate(weights = weights(W.out))

total_weights <- sum(dat9_exp2_weight$weights)
total_n <- nrow(dat9_exp2_weight)
dat9_exp2_weight <- dat9_exp2_weight %>%
  mutate(weights = weights / total_weights * total_n)

#-----------------------
# データへの加重の付与
#-----------------------
exclude_vars <- c("psu_rul", "psu_op", "psu_indep", 
                  "処置", "correct_dum", "dk_dum", "control_dum")

numeric_vars <- names(dat9_exp2_weight)[
  sapply(dat9_exp2_weight, is.numeric) &
  !(names(dat9_exp2_weight) %in% exclude_vars)
]

numeric_vars <- numeric_vars[numeric_vars != "weights"]

dat9_exp2_weight[numeric_vars] <- lapply(
  dat9_exp2_weight[numeric_vars],
  function(x) x / dat9_exp2_weight$weights
)

#----------------------------
# 加重付与済みデータの再形成
#----------------------------
dat9_exp2w <- dat9_exp2_weight %>%
  dplyr::select(
    quiz_score, psu_rul, psu_op, psu_indep,
    age, income, gender, education,
    cabapp, keiki, kurashimuki,
    処置, correct_dum, dk_dum, control_dum, weights, psu
  ) %>% 
  na.omit()

【追試】図9-10:【実験 9─2】党派性解答スコアの党派性差異のプロット

【追試】図9-11:【実験9─2】処置のもとでの党派性差異

【追試】図9-12:【実験9─2】最小二乗法による経済評価の解答値と内閣支持率の解答値の関係の分析(党派性ごとのサンプル)

#----------------------------
# データの読み込みと変数作成
#----------------------------
data <- dat9_exp2w %>% 
  dplyr::select(cabapp, keiki, kurashimuki, psu_rul, psu_op, psu_indep,
         age, education, income, gender) %>% 
  na.omit()

#-------------------------
# 各党派サンプルのOLS推定
#-------------------------
# サブセットを利用して、各党派サンプルごとの回帰モデルを推定
model_rul   <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_rul == 1))
model_op    <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_op == 1))
model_indep <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_indep == 1))

#----------------
# 推定結果の成形
#----------------
maketib <- function(model, label) {
  tidy(model) %>% mutate(model = label)
}

df_rul   <- maketib(model_rul, "与党派サンプル")
df_op    <- maketib(model_op, "野党派サンプル")
df_indep <- maketib(model_indep, "無党派サンプル")

all_df <- bind_rows(df_rul, df_op, df_indep)

filtered_df <- all_df %>% 
  filter(term %in% c("psu_rul", "psu_op", "psu_indep", "keiki", "kurashimuki"))

filtered_df <- filtered_df %>%
  mutate(conf.low = estimate - 1.96 * std.error,
         conf.high = estimate + 1.96 * std.error)

filtered_df <- filtered_df %>%
  mutate(term_jp = case_when(
    term == "psu_rul"    ~ "与党支持",
    term == "psu_op"     ~ "野党支持",
    term == "psu_indep"  ~ "無党派",
    term == "keiki"      ~ "景気",
    term == "kurashimuki"~ "暮らし向き",
    TRUE ~ term
  ))

filtered_df <- filtered_df %>%
  mutate(model = factor(model, levels = c("与党派サンプル", "野党派サンプル", "無党派サンプル")))

filtered_df <- filtered_df %>%
  mutate(highlight = (conf.low > 0 & conf.high > 0) | (conf.low < 0 & conf.high < 0))

#----------------
# プロットの作成
#----------------
pd <- position_dodge(0.2)
ggplot(filtered_df, aes(x = term_jp, y = estimate)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "black", size = 0.5) +
  geom_rect(data = subset(filtered_df, highlight == TRUE),
            aes(xmin = as.numeric(factor(term_jp)) - 0.4,
                xmax = as.numeric(factor(term_jp)) + 0.4,
                ymin = conf.low, ymax = conf.high),
            fill = "grey90", alpha = 0.5, inherit.aes = FALSE, position = pd) +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2, color = "black", position = pd) +
  geom_point(size = 3, shape = 21, fill = "white", color = "black", position = pd) +
  geom_text(data = subset(filtered_df, highlight == TRUE),
            aes(label = paste0(round(estimate, 2), "\n[", round(conf.low, 2), ", ", round(conf.high, 2), "]")),
            hjust = -0.3, size = 3.5, color = "black", position = pd) +
  facet_wrap(~ model, ncol = 3) +
  xlab("独立変数") + ylab("係数") +
  ggtitle("OLS推定結果(内閣支持率解答)") +
  theme_bw() +
  theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1),
        text = element_text(family = "jpfont"))

【追試】図9-13:【実験9-2】最小二乗法による経済評価の解答値と内閣支持率の解答値の関係の分析(処置の効果)

エントロピー・バランシングによるデータへの重みづけ

以下では、エントロピー・バランシングにより、処置群に対して重みを付与するための計算を行う。統制群の重みを1とし、処置群に対して、eb.out$wを割り当てるための計算となる。

#------------------------------
# 加重算出のためのデータの設定
#------------------------------
dat9_exp2eb <- dat9_exp2 %>%
  dplyr::select(
    quiz_score, psu_rul, psu_op, psu_indep, group_quiz,
    age, income, gender, education, 
    cabapp, keiki, kurashimuki,
    処置, correct_dum, dk_dum, control_dum
  ) %>%
  na.omit() %>%
  mutate(
    treat = ifelse(control_dum == 1, 0, 1)
  )

#--------------------------------------------
# エントロピー・バランシングによる加重の算出
#--------------------------------------------
X <- as.matrix(dat9_exp2eb %>% 
                 dplyr::select(age, gender, education, income, psu_rul))

invisible(
  capture.output(
eb.out <- ebal::ebalance(Treatment = dat9_exp2eb$treat, X = X)
  )
)

dat9_exp2eb <- dat9_exp2eb %>%
  mutate(ebal_weights = ifelse(treat == 1, eb.out$w, 1))

#--------------
# 重みの正規化
#--------------
total_weights <- sum(dat9_exp2eb$ebal_weights)
total_n <- nrow(dat9_exp2eb)
dat9_exp2eb <- dat9_exp2eb %>%
  mutate(ebal_weights_nm = ebal_weights / total_weights * total_n)


#-----------------------
# データへの加重の付与
#-----------------------
weighted_data <- dat9_exp2eb

numeric_vars <- names(weighted_data)[sapply(weighted_data, is.numeric)]

exclude_vars <- c("psu_rul", "psu_op", "psu_indep", 
                  "処置", "correct_dum", "dk_dum", "control_dum",
                  "ebal_weights", "ebal_weights_nm", "treat")

numeric_vars <- numeric_vars[!numeric_vars %in% exclude_vars]

weighted_data[numeric_vars] <- lapply(weighted_data[numeric_vars],
                                      function(x) x / weighted_data$ebal_weights_nm)

#---------------------------
#加重付与済みデータの再成形
#---------------------------
dat9_exp2eb <- weighted_data %>%
  dplyr::select(
    quiz_score, psu_rul, psu_op, psu_indep, group_quiz,
    age, income, gender, education, 
    cabapp, keiki, kurashimuki,
    処置, correct_dum, dk_dum, control_dum
  ) %>%
  na.omit()

【追試】図9-10:【実験 9─2】党派性解答スコアの党派性差異のプロット

【追試】図9-11:【実験9─2】処置のもとでの党派性差異

【追試】図9-12:【実験9─2】最小二乗法による経済評価の解答値と内閣支持率の解答値の関係の分析(党派性ごとのサンプル)

#----------------------------
# データの読み込みと変数作成
#----------------------------
data <- dat9_exp2eb %>% 
  dplyr::select(cabapp, keiki, kurashimuki, psu_rul, psu_op, psu_indep,
         age, education, income, gender) %>% 
  na.omit()

data <- data %>%
  mutate(
    psu_rul = case_when(
      psu_rul >= 1 ~ 1,
      psu_rul < 1  ~ 0
    ),
    psu_op = case_when(
      psu_op >= 1 ~ 1,
      psu_op < 1  ~ 0
    ),
    psu_indep = case_when(
      psu_indep >= 1 ~ 1,
      psu_indep < 1  ~ 0
    )
  )

#-------------------------
# 各党派サンプルのOLS推定
#-------------------------
model_rul   <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_rul == 1))
model_op    <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_op == 1))
model_indep <- lm(cabapp ~ keiki + kurashimuki + age + education + income + gender, 
                  data = subset(data, psu_indep == 1))

#----------------
# 推定結果の成形
#----------------
gettd <- function(model, label) {
  tidy(model) %>% mutate(model = label)
}

df_rul   <- gettd(model_rul, "与党派サンプル")
df_op    <- gettd(model_op, "野党派サンプル")
df_indep <- gettd(model_indep, "無党派サンプル")

all_df <- bind_rows(df_rul, df_op, df_indep)

filtered_df <- all_df %>% 
  filter(term %in% c("psu_rul", "psu_op", "psu_indep", "keiki", "kurashimuki"))

filtered_df <- filtered_df %>%
  mutate(conf.low = estimate - 1.96 * std.error,
         conf.high = estimate + 1.96 * std.error)

filtered_df <- filtered_df %>%
  mutate(term_jp = case_when(
    term == "psu_rul"    ~ "与党支持",
    term == "psu_op"     ~ "野党支持",
    term == "psu_indep"  ~ "無党派",
    term == "keiki"      ~ "景気",
    term == "kurashimuki"~ "暮らし向き",
    TRUE ~ term
  ))

filtered_df <- filtered_df %>%
  mutate(model = factor(model, levels = c("与党派サンプル", "野党派サンプル", "無党派サンプル")))

filtered_df <- filtered_df %>%
  mutate(highlight = (conf.low > 0 & conf.high > 0) | (conf.low < 0 & conf.high < 0))

#----------------
# プロットの作成
#----------------
pd <- position_dodge(0.2)
ggplot(filtered_df, aes(x = term_jp, y = estimate)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "black", size = 0.5) +
  geom_rect(data = subset(filtered_df, highlight == TRUE),
            aes(xmin = as.numeric(factor(term_jp)) - 0.4,
                xmax = as.numeric(factor(term_jp)) + 0.4,
                ymin = conf.low, ymax = conf.high),
            fill = "grey90", alpha = 0.5, inherit.aes = FALSE, position = pd) +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2, color = "black", position = pd) +
  geom_point(size = 3, shape = 21, fill = "white", color = "black", position = pd) +
  geom_text(data = subset(filtered_df, highlight == TRUE),
            aes(label = paste0(round(estimate, 2), "\n[", round(conf.low, 2), ", ", round(conf.high, 2), "]")),
            hjust = -0.3, size = 3.5, color = "black", position = pd) +
  facet_wrap(~ model, ncol = 3) +
  xlab("独立変数") + ylab("係数") +
  ggtitle("OLS推定結果(内閣支持率解答)") +
  theme_bw() +
  theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1),
        text = element_text(family = "jpfont"))

【追試】図9-13:【実験9-2】最小二乗法による経済評価の解答値と内閣支持率の解答値の関係の分析(処置の効果)

第10章:日本の経済投票はどのようなものなのか?―実験データの分析(3))

【補足】推定方法の説明

コンジョイント実験のデータをどのように分析するか?

本分析では、Hainmueller, Hopkins, and Yamamoto (2014) に準拠した形で、各属性の選択確率について 最小二乗法(線形確率モデル:Linear probability model)を用いて推定を行う。 具体的には、被験者\(i=1,...,N\)、提示される各プロフィールの番号\(j=1,...,J\) 、および被験者に提示される質問(タスク)の回数\(k=1,...,K\) に対して、次のようなモデルを設定する。

GDP成長率:

\[\begin{eqnarray} E_{i,j,k}^{GDP} &=& \gamma_0 + \gamma_1\,GDP_{(2i,j,k)} + \gamma_2\,GDP_{(3i,j,k)} + \varepsilon_{i,j,k} \end{eqnarray}\]

完全失業率:

\[\begin{eqnarray} E_{i,j,k}^{Unemp} &=& \delta_0 + \delta_1\,Unemp_{(2i,j,k)} + \delta_2\,Unemp_{(3i,j,k)} + \varepsilon_{i,j,k} \end{eqnarray}\]

物価:

\[\begin{eqnarray} E_{i,j,k}^{Price} &=& \zeta_0 + \zeta_1\,Price_{(2i,j,k)} + \zeta_2\,Price_{(3i,j,k)} + \varepsilon_{i,j,k} \end{eqnarray}\]

日経平均株価:

\[\begin{eqnarray} E_{i,j,k}^{Price} &=& \eta_0 + \eta_1\,Price_{(2i,j,k)} + \eta_2\,Price_{(3i,j,k)} + \varepsilon_{i,j,k} \end{eqnarray}\]

為替レート:

\[\begin{eqnarray} E_{i,j,k}^{Exchange} &=& \kappa_0 + \kappa_1\,Exchange_{(2i,j,k)} + \kappa_2\,Exchange_{(3i,j,k)} + \varepsilon_{i,j,k} \end{eqnarray}\]

長期金利:

\[\begin{eqnarray} E_{i,j,k}^{Interest} &=& \lambda_0 + \lambda_1\,Interest_{(2i,j,k)} + \lambda_2\,Interest_{(3i,j,k)} + \varepsilon_{i,j,k} \end{eqnarray}\]

ここで、\(E^{GDP}_{i,j,k}\)は「被験者\(i\)が、質問\(k\)において提示されたプロフィール\(j\)のGDP成長率レベルを受容(または選択)したかどうかを示す2値変数」とする。その他の属性(完全失業率、物価、日経平均株価、為替レート、長期金利)についても同様である。また、\(GDP_{(2i,j,k)}\)、および\(GDP_{(3i,j,k)}\)は、それぞれ GDP 成長率の水準が2、3であることを示すダミー変数(基準水準を 1 としている)であり、他の属性についても同様に、水準2および水準3であることを示すダミー変数を用いている。

本文の補足分析と各図表のコード

図10-4:【実験10-1A・YCS/実験10-1B・Cint】コンジョイント分析の結果(全体)

#-----------------
# 関数の読み込み
#-----------------
source("plot10_4.R")

#------------------------------------------------
# 共通の要因リスト、ベースライン、デザインの設定
#------------------------------------------------
attribute_list <- list(
  "GDP成長率" = c("前期比低下","変化なし","前期比上昇"),
  "完全失業率" = c("前年同月比低下","変化なし","前年同月比上昇"),
  "物価"       = c("前年同月比低下","変化なし","前年同月比上昇"),
  "日経平均株価" = c("年初来低下","変化なし","年初来上昇"),
  "為替レート"  = c("年初から円安方向","変化なし","年初から円高方向"),
  "長期金利"     = c("前年同期から低下","変化なし","前年同期から上昇")
)

baseline <- list(
  "GDP成長率"   = "変化なし",
  "完全失業率"  = "変化なし",
  "物価"        = "変化なし",
  "日経平均株価" = "変化なし",
  "為替レート"  = "変化なし",
  "長期金利"    = "変化なし"
)


common_design <- makeDesign(
  type='constraints',
  attribute.levels=attribute_list
)



#-----------------------------------
# コンジョイント実験データのOLS推定
#-----------------------------------
#-------与党選択についての推定
conjoint_data_ruling <- plot10_4(
  filepath = "experiment_conjoint_ind.csv",
  responses= c("Q4.2","Q4.3","Q4.4","Q4.5","Q4.6"),
  label_name= "与党選択"
)

#-------野党選択についての推定
conjoint_data_opposite <- getConjointResult(
  filepath = "experiment_conjoint_ind.csv",
  responses= c("Q5.2","Q5.3","Q5.4","Q5.5","Q5.6"),
  label_name= "野党選択"
)

#-------投票忌避選択についての推定
conjoint_data_ind <- getConjointResult(
  filepath = "experiment_conjoint_ind.csv",
  responses= c("Q6.2","Q6.3","Q6.4","Q6.5","Q6.6"),
  label_name= "投票忌避"
)

#--------------------------------
# 推定結果についてのデータの成形
#--------------------------------
df_conj_full <- rbind(
  conjoint_data_ruling,
  conjoint_data_opposite,
  conjoint_data_ind
)

df_conj_full$highlight <- with(df_conj_full, (low > 0 & up > 0) | (low < 0 & up < 0))

df_conj_full <- transform(
  df_conj_full,
  投票選択 = factor(投票選択, levels = c("与党選択","野党選択","投票忌避")),
  経済指標 = factor(経済指標,
              levels = c("長期金利:上昇", "為替:年初から円安", "日経平均:年初来低下",
                         "物価:前年同月比上昇", "失業率:前年同月比上昇", "GDP成長率:前期比低下",
                         "長期金利:低下", "為替:年初から円高", "日経平均:年初来上昇",
                         "物価:前年同月比低下", "失業率:前年同月比低下", "GDP成長率:前期比上昇"))
)

df_conj_full <- df_conj_full %>%
  mutate(
    indicator_position = as.numeric(経済指標),
    xmin = indicator_position - 0.4,
    xmax = indicator_position + 0.4
  )

#-----------------
# プロットの作成
#-----------------
pd <- position_dodge(width=0.4)

ggplot(df_conj_full, 
       aes(x = 経済指標, y = AMCE, ymin = low, ymax = up,
           group = 投票選択, linetype = 投票選択)) +
  geom_hline(yintercept = 0, color = "black", size = 0.5) +
  
  geom_errorbar(position = pd, color="black", size=0.4, width=0.1) +
  geom_point(position = pd, size=3, shape=21, fill="white", color="black") +
  
  geom_rect(
    data = subset(df_conj_full, highlight == TRUE),
    aes(xmin=xmin, xmax=xmax, ymin=low, ymax=up),
    fill = "grey90", alpha=0.5, inherit.aes=FALSE
  ) +
  
  scale_y_continuous(limits=c(-0.15,0.15), breaks=seq(-0.15,0.15,0.05)) +
  coord_cartesian(ylim=c(-0.15,0.15)) +
  xlab("経済指標の上昇/低下") + ylab("平均限界要素別効果 (AMCE)") +
  ggtitle("実験A") +
  theme_bw() +
  coord_flip() +
  scale_linetype_manual(values=c("与党選択"="solid","野党選択"="dotted","投票忌避"="longdash")) +
  geom_segment(aes(x=6.4, xend=6.4, y=-Inf, yend=Inf),
               color="black", size=0.5, linetype="dashed") +
  annotate("text", x=12.2, y=-0.125, label="[肯定的情報]", color="black") +
  annotate("text", x=6, y=-0.125,  label="[否定的情報]",  color="black") +
  theme(
    legend.position=c(0.9,0.1),
    legend.key.size=unit(0.6,"cm"),
    axis.text=element_text(size=10,color="black"),
    axis.text.y=element_text(size=8,color="black"),
    plot.title=element_text(hjust=.5,face="bold")
  )

図10-5:【実験A】コンジョイント分析の結果(党派別)

#-----------------
# 関数の読み込み
#-----------------
source("plot10_5.R")
source("plot10_5conj.R")


#-------------------
# データの読み込み
#-------------------
invisible(
  capture.output(conjoint_data_ruling <- na.omit(cjoint::read.qualtrics("experiment_conjoint_cint2023.csv",
                                               responses=c("Q8.2","Q8.3", "Q8.4","Q8.5",
                                                           "Q8.6"),
                                               covariates = c("Q2.1","Q2.2","Q2.4","Q2.7"),
                                               respondentID="ID",new.format = F))
  )
)


invisible(
  capture.output(
conjoint_data_opposite <- na.omit(cjoint::read.qualtrics("experiment_conjoint_cint2023.csv",
                                                 responses=c("Q9.2","Q9.3", "Q9.4","Q9.5",
                                                             "Q9.6"),
                                                 covariates = c("Q2.1","Q2.2","Q2.4","Q2.7"),
                                                 respondentID="ID",new.format = F))
  )
)


invisible(
  capture.output(
conjoint_data_ind <- na.omit(cjoint::read.qualtrics("experiment_conjoint_cint2023.csv",
                                            responses=c("Q2","Q3", "Q4","Q5",
                                                        "Q6"),
                                            covariates = c("Q2.1","Q2.2","Q2.4","Q2.7"),
                                            respondentID="ID",new.format = F))
  )
)

#----------------------------------------------------------------
# 共通の要因リスト、ベースライン、デザインの設定(図10-4と同様)
#----------------------------------------------------------------
attribute_list <- list(
  "GDP成長率"   = c("前期比低下","変化なし","前期比上昇"),
  "完全失業率"  = c("前年同月比低下","変化なし","前年同月比上昇"),
  "物価"        = c("前年同月比低下","変化なし","前年同月比上昇"),
  "日経平均株価" = c("年初来低下","変化なし","年初来上昇"),
  "為替レート"  = c("年初から円安方向","変化なし","年初から円高方向"),
  "長期金利"     = c("前年同期から低下","変化なし","前年同期から上昇")
)

baseline <- list(
  "GDP成長率"   = "変化なし",
  "完全失業率"  = "変化なし",
  "物価"        = "変化なし",
  "日経平均株価" = "変化なし",
  "為替レート"  = "変化なし",
  "長期金利"    = "変化なし"
)

common_design <- makeDesign(
  type             = "constraints",
  attribute.levels = attribute_list
)


#----------------------------------------------------------------
# データのサブセットの設定とコンジョイント実験のデータのOLS推定
#----------------------------------------------------------------
#---- 与党選択
#与党派
conjoint_ruling_ruling <- subset(conjoint_data_ruling, Q2.7==1|Q2.7==3)
df_ruling_ruling <- plot10_5(conjoint_ruling_ruling, label_party="与党派", label_vote="与党選択")

#野党派
conjoint_ruling_opposite <- subset(conjoint_data_ruling, Q2.7 %in% c(2,4,5,6,7,8,9,11))
df_ruling_opposite <- plot10_5(conjoint_ruling_opposite, label_party="野党派", label_vote="与党選択")

#無党派
conjoint_ruling_ind <- subset(conjoint_data_ruling, Q2.7==12)
df_ruling_ind <- plot10_5(conjoint_ruling_ind, label_party="無党派", label_vote="与党選択")

df_conj_vote_ruling <- rbind(df_ruling_ruling, df_ruling_opposite, df_ruling_ind)

#---- 野党選択
#与党派
conjoint_opposite_ruling <- subset(conjoint_data_opposite, Q2.7==1|Q2.7==3)
df_opposite_ruling <- plot10_5(conjoint_opposite_ruling, label_party="与党派", label_vote="野党選択")

#野党派
conjoint_opposite_opposite <- subset(conjoint_data_opposite, Q2.7 %in% c(2,4,5,6,7,8,9,11))
df_opposite_opposite <- plot10_5(conjoint_opposite_opposite, label_party="野党派", label_vote="野党選択")

#無党派
conjoint_opposite_ind <- subset(conjoint_data_opposite, Q2.7==12)
df_opposite_ind <- plot10_5(conjoint_opposite_ind, label_party="無党派", label_vote="野党選択")

df_conj_vote_opposite <- rbind(df_opposite_ruling, df_opposite_opposite, df_opposite_ind)


#----投票忌避選択
#与党派
conjoint_ind_ruling <- subset(conjoint_data_ind, Q2.7==1|Q2.7==3)
df_ind_ruling <- plot10_5(conjoint_ind_ruling, label_party="与党派", label_vote="投票忌避")

#野党派
conjoint_ind_opposite <- subset(conjoint_data_ind, Q2.7 %in% c(2,4,5,6,7,8,9,11))
df_ind_opposite <- plot10_5(conjoint_ind_opposite, label_party="野党派", label_vote="投票忌避")

#無党派
conjoint_ind_ind <- subset(conjoint_data_ind, Q2.7==12)
df_ind_ind <- plot10_5(conjoint_ind_ind, label_party="無党派", label_vote="投票忌避")

df_conj_vote_ind <- rbind(df_ind_ruling, df_ind_opposite, df_ind_ind)


#-----------------
# プロットの作成
#-----------------
# 与党選択
k1 <- plot10_5conj(df_conj_vote_ruling,  "与党選択")
# 野党選択
k2 <- plot10_5conj(df_conj_vote_opposite,"野党選択")
# 投票忌避
k3 <- plot10_5conj(df_conj_vote_ind,     "投票忌避")


#-----------------
# プロットの表示
#-----------------
grid.arrange(k1,k2,k3, ncol=3)

【補足】図10-4:【実験10-1A・YCS/実験10-1B・Cint】コンジョイント分析の結果(全体)

コンジョイント実験においては、平均要素限界効果よりも、限界平均(marginal means)を用いた結果の解釈の方が望ましいとされている。本文では、一般的なACMEの結果を示したが、以下では、OLS推定をもとに限界平均を用いた結果を以下で示す。まず下記は、YCSのデータについての限界平均をもとにした推定結果である。

invisible(
  capture.output(
conjoint_data_ruling <- na.omit(read.qualtrics("experiment_conjoint_ind.csv",
                                responses=c("Q4.2","Q4.3", "Q4.4","Q4.5",
                                            "Q4.6"),
                                covariates = c("Q2.1","Q2.2","Q2.4","Q2.7"),
                                respondentID="ID",new.format = F))
  )
)
                                

invisible(
  capture.output(
conjoint_data_opposite <- na.omit(read.qualtrics("experiment_conjoint_ind.csv",
                                               responses=c("Q5.2","Q5.3", "Q5.4","Q5.5",
                                                           "Q5.6"),
                                               covariates = c("Q2.1","Q2.2","Q2.4","Q2.7"),
                                               respondentID="ID",new.format = F))
  )
)
                                               
invisible(
  capture.output(
conjoint_data_ind <- na.omit(read.qualtrics("experiment_conjoint_ind.csv",
                                                 responses=c("Q6.2","Q6.3", "Q6.4","Q6.5",
                                                             "Q6.6"),
                                                 covariates = c("Q2.1","Q2.2","Q2.4","Q2.7"),
                                                 respondentID="ID",new.format = F))   
  )
)
#-----------------
# 関数の読み込み
#-----------------
source("plot10_4factname.R")
source("plot10_4emmeans.R")
source("plot10_4makedf.R")
source("plot10_4mm.R")

#--------------------------------------
# 共通の要因と水準についての分類・整理
#--------------------------------------
factor_levels <- c("GDP成長率","完全失業率","物価","日経平均株価","為替レート","長期金利")


#---------------------------------------------
# OLS推定の実行と推定結果をもとにした図の作成
#---------------------------------------------
#---- 与党選択
conjoint_data_ruling <- conjoint_data_ruling %>%
  mutate(
    GDP成長率    = factor(GDP成長率),
    完全失業率   = factor(完全失業率),
    物価         = factor(物価),
    日経平均株価 = factor(日経平均株価),
    為替レート   = factor(為替レート),
    長期金利     = factor(長期金利)
  )
mod_ruling <- lm(selected ~ GDP成長率 + 完全失業率 + 物価 + 日経平均株価 + 為替レート +
                   長期金利,
                 data = conjoint_data_ruling)
df_rul_all <- plot10_4makedf(mod_ruling)

k1 <- plot10_4mm(df_rul_all, title_str="与党選択(Marginal means)")

#---- 野党選択
conjoint_data_opposite <- conjoint_data_opposite %>%
  mutate(
    GDP成長率    = factor(GDP成長率),
    完全失業率   = factor(完全失業率),
    物価         = factor(物価),
    日経平均株価 = factor(日経平均株価),
    為替レート   = factor(為替レート),
    長期金利     = factor(長期金利)
  )

mod_opposite <- lm(selected ~ GDP成長率 + 完全失業率 + 物価 + 日経平均株価 + 為替レート +
                     長期金利,
                   data = conjoint_data_opposite)
df_opp_all <- plot10_4makedf(mod_opposite)

k2 <- plot10_4mm(df_opp_all, title_str="野党選択(Marginal means)")

#---- 投票忌避
conjoint_data_ind <- conjoint_data_ind %>%
  mutate(
    GDP成長率    = factor(GDP成長率),
    完全失業率   = factor(完全失業率),
    物価         = factor(物価),
    日経平均株価 = factor(日経平均株価),
    為替レート   = factor(為替レート),
    長期金利     = factor(長期金利)
  )
mod_indep <- lm(selected ~ GDP成長率 + 完全失業率 + 物価 + 日経平均株価 + 為替レート + 長期金利,
                data = conjoint_data_ind)
df_ind_all <- plot10_4makedf(mod_indep)

k3<- plot10_4mm(df_ind_all, title_str="投票忌避(Marginal means)")

windows(240, 160)
grid.arrange(k1, k2, k3, ncol=3)

以下は、Cintのデータに関する結果である。

【補足】図10-5:【実験10-1A・YCS/実験10-1B・Cint】コンジョイント分析の結果(全体)

#-----------------
# 関数の読み込み
#-----------------
source("plot10_4factname.R")
source("plot10_5makedf.R")
source("plot10_5mm.R")

#--------------------------------------
# 共通の要因と水準についての分類・整理
#--------------------------------------
factor_levels <- c("GDP成長率","完全失業率","物価","日経平均株価","為替レート","長期金利")

#--------------------------------------------------------------
# コンジョイント実験のデータに対するOLS推定の結果とデータの成形
#--------------------------------------------------------------
#---- 与党選択についての整理
df_ruling_ruling <- subset(conjoint_data_ruling, Q2.7 %in% c(1,3))
mm_ruling_ruling <- plot10_5makedf(df_ruling_ruling, label_party="与党派", label_vote="与党選択")

df_ruling_opposite <- subset(conjoint_data_ruling, Q2.7 %in% c(2,4,5,6,7,8,9,11))
mm_ruling_opposite <- plot10_5makedf(df_ruling_opposite, label_party="野党派", label_vote="与党選択")

df_ruling_ind <- subset(conjoint_data_ruling, Q2.7==12)
mm_ruling_ind <- plot10_5makedf(df_ruling_ind, label_party="無党派", label_vote="与党選択")

df_vote_ruling <- rbind(mm_ruling_ruling, mm_ruling_opposite, mm_ruling_ind)

#---- 野党選択についての整理
df_opposite_ruling <- subset(conjoint_data_opposite, Q2.7 %in% c(1,3))
mm_opposite_ruling <- plot10_5makedf(df_opposite_ruling, label_party="与党派", label_vote="野党選択")

df_opposite_opposite <- subset(conjoint_data_opposite, Q2.7 %in% c(2,4,5,6,7,8,9,11))
mm_opposite_opposite <- plot10_5makedf(df_opposite_opposite, label_party="野党派", label_vote="野党選択")

df_opposite_ind <- subset(conjoint_data_opposite, Q2.7==12)
mm_opposite_ind <- plot10_5makedf(df_opposite_ind, label_party="無党派", label_vote="野党選択")

df_vote_opposite <- rbind(mm_opposite_ruling, mm_opposite_opposite, mm_opposite_ind)

#---- 投票忌避選択についての整理
df_ind_ruling <- subset(conjoint_data_ind, Q2.7 %in% c(1,3))
mm_ind_ruling <- plot10_5makedf(df_ind_ruling, label_party="与党派", label_vote="投票忌避選択")

df_ind_opposite <- subset(conjoint_data_ind, Q2.7 %in% c(2,4,5,6,7,8,9,11))
mm_ind_opposite <- plot10_5makedf(df_ind_opposite, label_party="野党派", label_vote="投票忌避選択")

df_ind_ind <- subset(conjoint_data_ind, Q2.7==12)
mm_ind_ind <- plot10_5makedf(df_ind_ind, label_party="無党派", label_vote="投票忌避選択")

df_vote_ind <- rbind(mm_ind_ruling, mm_ind_opposite, mm_ind_ind)

#---- 3種のデータの統合と整理
df_all <- rbind(df_vote_ruling, df_vote_opposite, df_vote_ind)

df_all <- df_all %>%
  rowwise() %>%
  mutate(
    category = plot10_4factname(FactorName, Level) 
  ) %>%
  ungroup() %>%
  mutate(
    facIndex = match(FactorName, factor_levels),
    offset = case_when(
      category=="肯定" ~ +0.2,
      category=="否定" ~ -0.2,
      TRUE             ~  0
    ),
    yPos = facIndex + offset
  )

#----------------
# プロットの作成
#----------------
df_ruling <- subset(df_all, vote_label=="与党選択") 
df_opposite <- subset(df_all, vote_label=="野党選択") 
df_ind <- subset(df_all, vote_label=="投票忌避選択") 

k1 <- plot10_5mm(df_ruling, factor_levels,  "与党選択")
k2 <- plot10_5mm(df_opposite, factor_levels, "野党選択")
k3 <- plot10_5mm(df_ind, factor_levels,    "投票忌避選択")


#----------------
# プロットの表示
#----------------
print(k1)

print(k2)

print(k3)

Cintのデータについての結果は以下の通りである。YCSCintのいずれのデータを用いた場合にも、本文の分析結果は支持できるものとなっている。

分析のためのヘルパー関数一覧と各関数の詳細

図番号 関数名
第1章 図1-1 plot1_1.R
図1-2
図1-3 plot1_3.R
図1-7 plot1_7.R
第2章 図2-2 plot2_2.R
図2-3 plot2_3.R
図2-4 plot2_4.R
図2-5 plot2_5df.R
plot2_5_1.R
plot2_5_2.R
第4章 図4-1 plot4_1.R
plot4_1anno.R
図4-2 plot4_2.R
plot4_2anno.R
図4-4 plot4_4df.R
plot4_4_1.R
plot4_4_2.R
第6章 図6-2 plot6_2df.R
図6-3 plot6_2.R
図6-4 plot6_4df.R
図6-5 plot6_4summary.R
plot6_4ttest.R
plot6_4.R
図6-6 plot6_6.R
第7章 図7-2 plot7_2df.R
plot7_2.df
図7-3 plot7_3df.R
plot7_3.R
図7-6 plot7_6.R
第8章 図8-4 plot8_4.R
補足・順序ロジット推定 ologit8_exp1.R
図8-15 plot8_exp2sim15.R
図8-16 plot8_exp2sim16.R
plot8_exp2df.R
plot8_exp2.R
第9章 図9-4 plot9_exp1hl.R
plot9_exp1.R
図9-9 plot9_exp2bar1.R
plot9_exp2bar2.R
図9-10 plot9_exp2sim.R
図9-11 plot9_exp2sim2.R
第10章 図10-4 plot10_4.R
図10-5 plot10_5.R
plot10_5conj.R
補足・図10-4 plot10_4factname.R
plot10_4emmeans.R
plot10_4makedf.R
plot10_4mm.R
補足・図10-5 plot10_4factname.R
plot10_5makedf.R
plot10_5mm.R

第1章

plot1_1.R(図1-1と図1-2)

plot1_1 <- function(df, y_col_negative, y_col_positive, title_negative, title_positive) {
  
  p.mid <- ggplot(df, aes(x = 1, y = year_graph)) +
    geom_text(aes(label = year_graph)) +
    geom_segment(aes(x = 0.94, xend = 0.96, yend = year_graph)) +
    geom_segment(aes(x = 1.04, xend = 1.065, yend = year_graph)) +
    ggtitle("") +
    ylab(NULL) +
    theme_common() +
    scale_x_reverse()
  
  p1 <- ggplot(data = df, aes(x = as.Date(yearmon, "%Y-%m-%d"), y = !!sym(y_col_negative))) + 
    geom_bar(stat = "identity") + 
    ggtitle(title_negative) +
    theme_common() +
    coord_flip() +
    ylim(100, 0)
  
  p2 <- ggplot(data = df, aes(x = as.Date(yearmon, "%Y-%m-%d"), y = !!sym(y_col_positive))) + 
    geom_bar(stat = "identity") + 
    ggtitle(title_positive) +
    theme_common() +
    coord_flip() +
    ylim(0, 100)
  
  return(list(p1, p.mid, p2))
}

theme_common <- function() {
  theme(
    axis.title = element_blank(),
    panel.grid = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank(),
    panel.background = element_blank(),
    axis.text.x = element_text(color = NA),
    axis.ticks.x = element_line(color = NA),
    plot.margin = unit(c(1, -1, 1, 0), "mm")
  )
}

plot1_3.R(図1-3)

plot1_3 <- function(df, title_neg, title_pos) {
  
  p.mid <- ggplot(df, aes(x = 1, y = 選挙年)) +
    geom_text(aes(label = 選挙年)) +
    geom_segment(aes(x = 0.94, xend = 0.96, yend = 選挙年)) +
    geom_segment(aes(x = 1.04, xend = 1.065, yend = 選挙年)) +
    theme_common() +
    theme(text = element_text(family = "jpfont"))+
    scale_x_reverse()
  
  p1 <- ggplot(data = df, aes(x = 選挙年, y = 否定)) +
    geom_bar(stat = "identity") + ggtitle(title_neg) +
    theme_common() +
    scale_y_reverse() + coord_flip() + ylim(100, 0) +
    geom_label(aes(label = round(否定, 2), y = 否定 + 0.05),
               color = "black", size = 4.0, fill = "white", label.size = 0.25) +
    theme(text = element_text(family = "jpfont"))+
    theme_bw()+ 
    scale_x_continuous(breaks = NULL)
  
  p2 <- ggplot(data = df, aes(x = 選挙年, y = 肯定)) +
    geom_bar(stat = "identity") + ggtitle(title_pos) +
    theme_common() +
    scale_y_reverse() + coord_flip() + ylim(0, 100) +
    geom_label(aes(label = round(肯定, 2), y = 肯定 + 0.05),
               color = "black", size = 4.0, fill = "white", label.size = 0.25) +
    theme(text = element_text(family = "jpfont"))+
    theme_bw()+ 
    scale_x_continuous(breaks = NULL)
  
  
  return(list(p1, p.mid, p2))
}

theme_common <- function() {
  theme(
    axis.title = element_blank(),
    panel.grid = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank(),
    panel.background = element_blank(),
    axis.text.x = element_text(color = NA),
    axis.ticks.x = element_line(color = NA),
    plot.margin = unit(c(1, -1, 1, -1), "mm")
  )
}

theme_bar <- function() {
  theme_common() +
    theme(axis.title.x = element_blank(), 
          axis.title.y = element_blank(), 
          plot.margin = unit(c(1, -1, 1, 0), "mm")) +
    scale_y_reverse() + coord_flip() + ylim(1.0, 0)
}

plot1_7.R(図1-7)

plot1_7<- function(data, fill_column, title_suffix) {
  
  p.mid <- ggplot(data, aes(x = 1, y = 選挙年)) + 
    geom_text(aes(label = 選挙年)) +
    geom_segment(aes(x = 0.94, xend = 0.96, yend = 選挙年)) +
    geom_segment(aes(x = 1.04, xend = 1.065, yend = 選挙年)) +
    ggtitle("") + ylab(NULL) +
    scale_x_continuous(expand = c(0, 0), limits = c(0.94, 1.065)) +
    theme(axis.title = element_blank(), panel.grid = element_blank(),
          axis.text.y = element_blank(), axis.ticks.y = element_blank(),
          panel.background = element_blank(), axis.text.x = element_text(color = NA),
          axis.ticks.x = element_line(color = NA), plot.margin = unit(c(1, -1, 1, -1), "mm")) + 
    scale_x_reverse()
  
  p1 <- ggplot(data = subset(data, 政党支持 == "与党派"), aes(x = 選挙年, y = 値, fill = fill_column)) +
    geom_bar(stat = "identity") + ggtitle(paste("与党派", title_suffix)) +
    theme(axis.title.x = element_blank(), axis.title.y = element_blank(), 
          axis.text.y = element_blank(), axis.ticks.y = element_blank(),
          plot.margin = unit(c(1, -1, 1, 0), "mm")) + coord_flip() +
    ylim(c(0, 0.6)) + scale_fill_manual(values = c("grey", "black")) + 
    theme(legend.position = "none") + theme_bw()
  
  p2 <- ggplot(data = subset(data, 政党支持 == "野党派"), aes(x = 選挙年, y = 値, fill = fill_column)) +
    geom_bar(stat = "identity") + ggtitle(paste("野党派", title_suffix)) +
    theme(axis.title.x = element_blank(), axis.title.y = element_blank(), 
          axis.text.y = element_blank(), axis.ticks.y = element_blank(),
          plot.margin = unit(c(1, -1, 1, 0), "mm")) + coord_flip() +
    ylim(c(0, 0.6)) + scale_fill_manual(values = c("grey", "black")) + 
    theme(legend.position = "none") + theme_bw()
  
  p3 <- ggplot(data = subset(data, 政党支持 == "無党派"), aes(x = 選挙年, y = 値, fill = fill_column)) +
    geom_bar(stat = "identity") + ggtitle(paste("無党派", title_suffix)) +
    theme(axis.title.x = element_blank(), axis.title.y = element_blank(), 
          axis.text.y = element_blank(), axis.ticks.y = element_blank(),
          legend.position = c(0.9, 0.2)) + coord_flip() +
    ylim(c(0, 0.6)) + scale_fill_manual(values = c("grey", "black")) + theme_bw()
  
  list(p1 = p1, p2 = p2, p3 = p3, p.mid = p.mid)
}

第2章

plot2_2.R(図2-2)

plot2_2 <- function(data, cols, labels, main_title) {
  dfs <- lapply(1:length(cols), function(i) {
    valid_data <- data[!is.na(data[[cols[i]]]), ]
    
    if(nrow(valid_data) == 0) return(NULL)  
    
    df <- data.frame(
      Date = as.Date(valid_data$yearmon),
      Value = valid_data[[cols[i]]],
      Label = labels[i]
    )
    return(df)
  })
  
  df <- do.call(rbind, dfs)
  
  p <- ggplot(df, aes(x = Date, y = Value, fill = Label)) +
    geom_area() +
    scale_fill_grey() +
    scale_color_grey() +
    labs(fill = "", title = main_title) +
    xlab("年") +
    ylab("") +
    theme_bw()
  
  return(p)
}

plot2_3.R(図2-3)

plot2_3 <- function(data, title, y_max) {
  ggplot(data, aes(x = as.Date(yearmon, "%Y-%m-%d"), y = value)) + 
    geom_line(aes(linetype = 経済評価), size = 1) +
    theme_minimal() +
    xlab("年") +
    ylab("各種の回答割合(%)") +
    ggtitle(title) +
    geom_vline(data = events, aes(xintercept = date), linetype = "dashed") +
    geom_text(data = events, aes(x = date, y = y_max, label = label), 
              angle = 315, size = 2, hjust = 0, vjust = 1.2)
}

plot2_4.R(図2-4)

plot2_4 <- function(data, y_var1, y_var2, title, y_max, legend_title) {
  ggplot(data, aes(x = as.Date(yearmon, "%Y-%m-%d"))) +
    geom_line(aes(y = .data[[y_var1]], linetype = "肯定"), color = "black") +
    geom_line(aes(y = .data[[y_var2]], linetype = "否定"), color = "black") +
    scale_linetype_manual(name = legend_title, values = c("肯定" = "solid", "否定" = "dashed")) +
    theme_minimal() +
    xlab("年") +
    ylab("各種の回答割合(%)") +
    ggtitle(title) +
    theme(legend.position = "right") +
    geom_segment(data = business_cycles,
                 aes(x = start, xend = end, y = y_max, yend = y_max),
                 inherit.aes = FALSE, size = 1.5, color = "black")
}

plot2_5df.R(図2-5)

plot2_5df <- function(yearmon_data, main_data, new_names) {
  df <- data.frame(yearmon_data, na.omit(main_data))
  colnames(df) <- new_names
  
  df_long <- df %>% 
    tidyr::pivot_longer(
      cols = all_of(new_names[-1]),
      names_to = "key",
      values_to = "value"
    )
  
  return(df_long)
}

plot2_5_1.R(図2-5)

plot2_5_1 <- function(tb_long, title, date_col, value_col, linetype_col) {
  p <- ggplot2::ggplot(tb_long) + 
    geom_rect(data = admin, aes(xmin = start, xmax = end, ymin = -Inf, ymax = Inf), fill = c("lightgrey")) +
    geom_line(aes(x = as.Date(年, "%Y-%m-%d"), y = value, linetype = key), size = 1) +
    scale_linetype_discrete(name = "党派性", breaks = c("与党派", "野党派")) +  # Legendのタイトルと順番を指定
    theme_minimal() +
    xlab("年") +
    ylab(value_col) +
    ggtitle(title) + 
    theme(legend.position = c(0.95, 0.95),
          text = element_text(family = "noto"))
  return(p)
}

plot2_5_2.R(図2-5)

plot2_5_2 <- function(df, title, linetype_col, y_col) {
  p <- ggplot2::ggplot(df) + 
    geom_rect(data = admin, aes(xmin = start, xmax = end, ymin = -Inf, ymax = Inf), fill = c("lightgrey")) +
    geom_line(aes(x = as.Date(年, "%Y-%m-%d"), y = df[[y_col]], linetype = df[[linetype_col]]), size = 1) +
    theme_minimal() +
    xlab("年") +
    ylab(y_col) +
    ggtitle(title) + 
    theme(legend.position = c(0.95, 0.95))
  return(p)
}

第4章

plot4_1.R(図4-1)

plot4_1 <- function(data, y_label, title) {
  df <- data.frame(yearmon, data)
  colnames(df) <- c("yearmon", y_label)
  
  p <- ggplot(df, aes(x = as.Date(yearmon, "%Y-%m-%d"), y = !!sym(y_label))) + 
    geom_line(size = 1) +
    theme_minimal() +
    xlab("年") +
    coord_cartesian(ylim = c(5, 75))  +
    ylab("割合(%)") +
    plot4_1anno() +
    ggtitle(title)
  
  return(p)
}

plot4_1anno.R(図4-1)

plot4_1anno <- function() {
  events <- data.frame(
    date = as.Date(c("1973-10-01", "1989-04-01", "1990-01-01", "1997-07-01", "2008-09-01", "2011-03-01", "2012-12-01")),
    label = c("第1次石油ショック(1973)", "消費税導入(1989)", "バブル経済崩壊(1990)", "アジア通貨危機(1997)", "グローバル経済危機(2008)", "東日本大震災(2011)", "アベノミクス導入(2012)"),
    y = c(40, 40, 40, 40, 40, 40, 40)  
  )
  offset_x <- 300  
  offset_y <- 10  
  
  list(
    geom_vline(data = events, aes(xintercept = date), linetype = "dashed"),
    geom_segment(
      data = events,
      aes(x = date, y = y - 5, xend = date + offset_x, yend = y + offset_y),
      arrow = arrow(length = unit(0.1, "cm")),
      color = "black"
    ),
    
    geom_text(
      data = events,
      aes(x = date + offset_x, y = y + offset_y, 
          label = label),
      angle = 30,  
      hjust = 0,
      size = 3
    )
  )
}

plot4_2.R(図4-2)

plot4_2 <- function(data, y_label, title) {
  df <- data.frame(yearmon, data)
  colnames(df) <- c("yearmon", y_label)
  
  p <- ggplot(df, aes(x = as.Date(yearmon, "%Y-%m-%d"), y = !!sym(y_label))) + 
    geom_line(size = 1) +
    theme_minimal() +
    xlab("年") +
    coord_cartesian(ylim = c(5, 75))  +
    ylab("割合(%)") +
    plot4_2anno() +
    ggtitle(title)
  
  return(p)
}

plot4_2anno.R(図4-2)

plot4_2anno <- function() {
  events <- data.frame(
    date = as.Date(c("1973-10-01", "1989-04-01", "1990-01-01", "1997-07-01", "2008-09-01", "2011-03-01", "2012-12-01")),
    label = c("第1次石油ショック(1973)", "消費税導入(1989)", "バブル経済崩壊(1990)", "アジア通貨危機(1997)", "グローバル経済危機(2008)", "東日本大震災(2011)", "アベノミクス導入(2012)"),
    y = c(50, 50, 50, 50, 50, 50, 50)  
  )
  
  offset_x <- 300   
  offset_y <- 10   
  
  list(
    geom_vline(data = events, aes(xintercept = date), linetype = "dashed"),
    geom_segment(
      data = events,
      aes(x = date, y = y - 5, xend = date + offset_x, yend = y + offset_y),
      arrow = arrow(length = unit(0.1, "cm")),
      color = "black"
    ),
     geom_text(
      data = events,
      aes(x = date + offset_x, y = y + offset_y, label = label),
      angle = 30, 
      hjust = 0,
      size = 3
    )
  )
}

plot4_4df.R(図4-4)

plot4_4df <- function(yearmon, column1, column2, column_name) {
  data.frame(yearmon, column1, column2) %>%
    setNames(c("yearmon", "与党派", "野党派")) %>%
    pivot_longer(cols = -yearmon, names_to = "key", values_to = "value") %>%
    mutate(key = factor(key, levels = c("与党派", "野党派"))) %>%
    rename(!!column_name := key)
}

plot4_4_1.R(図4-4)

plot4_4_1 <- function(data, title, y_label, line_type_column) {
  ggplot(data) +
    geom_rect(data = admin, aes(xmin = start, xmax = end, ymin = -Inf, ymax = Inf), fill = "lightgrey") +
    geom_line(aes(x = as.Date(yearmon, "%Y-%m-%d"), y = value, linetype = !!rlang::sym(line_type_column)), linewidth = 1) +
    theme_bw() +
    xlab("年") +
    ylab(y_label) +
    ggtitle(title) +
    theme(legend.position = c(0.95, 0.55))
}

plot4_4_2.R(図4-4)

plot4_4_2 <- function(data, title, y_label) {
  ggplot(data) +
    geom_rect(data = admin, aes(xmin = start, xmax = end, ymin = -Inf, ymax = Inf), fill = "lightgrey") +
    geom_line(aes(x = as.Date(yearmon, "%Y-%m-%d"), y = 党派性差異), linewidth = 1) +
    theme_bw() +
    xlab("年") +
    ylab(y_label) +
    ggtitle(title) +
    theme(legend.position = c(0.95, 0.55))
}

第6章

plot6_2df.R(図6-2と図6-3)

plot6_2df <- function(df, measure_var) {
  group_income <- df$income
  group_income[df$income <= 3] <- "所得(低)"
  group_income[df$income > 3 & df$income < 6.666667] <- "所得(中)"
  group_income[df$income >= 6.666667] <- "所得(高)"
  
  processed_df <- data.frame(group_income, df[[measure_var]])
  colnames(processed_df) <- c("group_income", measure_var)
  processed_df <- na.omit(processed_df)
  processed_df[[measure_var]] <- as.numeric(processed_df[[measure_var]])
  processed_df
}

plot6_2tukey.R(図6-2と図6-3)

plot6_2tukey <- function(df, obj_var, group_var, alpha = 0.05) {
  tukey_result <- TukeyHSD(aov(df[[obj_var]] ~ df[[group_var]], data = df))
  significant <- tukey_result[[group_var]][,4] < alpha
  return(list(tukey_result = tukey_result, significant = significant))
}

plot6_2.R(図6-2と図6-3)

plot6_2 <- function(data, measure_var, title) {
  df_pr <- summarySE(data, measurevar = measure_var, groupvars = c("group_income"))
  df_pr$group_income <- factor(df_pr$group_income, levels = c("所得(低)", "所得(中)", "所得(高)"))
  
  pairwise_results <- pairwise.t.test(data[[measure_var]], data$group_income, p.adjust.method = "bonferroni")
  
  significant_pairs <- sum(pairwise_results$p.value < 0.05, na.rm = TRUE)
  
  if (significant_pairs >= 3) {
    bg_color <- "gray90"  
  } else if (significant_pairs >= 2) {
    bg_color <- "gray95"  
  } else if (significant_pairs >= 1) {
    bg_color <- "gray97"  
  } else {
    bg_color <- "white"  
  }

    pd <- position_dodge(0.4)
  
  y_label <- if (measure_var == "socio") {
    "社会志向"
  } else if (measure_var == "ego") {
    "個人志向"
  } else {
    measure_var
  }
  
  df_pr$mean_label <- round(df_pr[[measure_var]], 2)
  
  p <- ggplot(df_pr, aes(x = group_income, y = get(measure_var)), na.rm = TRUE) + 
    geom_errorbar(aes(ymin = get(measure_var) - 1.96 * se, ymax = get(measure_var) + 1.96 * se), size = 1, position = pd, width = .1, na.rm = TRUE) +
    geom_line(position = pd, na.rm = TRUE, group = 1) +
    geom_point(position = pd, size = 3, shape = 21, fill = "white") + 
    geom_text(aes(label = mean_label), vjust = -1.5, size = 3.5) +  
    xlab("") +
    ylab(y_label) +
    ggtitle(title) + 
    theme_bw() +
    theme(panel.background = element_rect(fill = bg_color, color = "black")) + 
    scale_x_discrete(guide = guide_axis(angle = 45)) +
    ylim(min(df_pr[[measure_var]] - df_pr$se) - 0.5, max(df_pr[[measure_var]] + df_pr$se) + 0.5) 
  
  return(p)
}

plot6_4df.R(図6-4と図6-5)

plot6_4df <- function(df, measure_var) {
  df <- df %>%
    mutate(
      group_income = case_when(
        income <= X ~ "所得(低)",
        income > X & income < XXX ~ "所得(中)",
        income >= XXX ~ "所得(高)"
      )
    ) %>%
    filter(!is.na(group_income) & !is.na(psu_indep) & !is.na(psu_rul) & !is.na(psu_op))
  df$group_income <- factor(df$group_income, levels = c("所得(低)", "所得(中)", "所得(高)"))
  df$psu_indep <- factor(df$psu_indep, levels = c(0, 1), labels = c("有党派", "無党派"), exclude = NULL) 
  df$psu_rul <- factor(df$psu_rul, levels = c(0, 1), labels = c("非与党派", "与党派"), exclude = NULL)
  df$psu_op <- factor(df$psu_op, levels = c(0, 1), labels = c("与党派", "非与党派"), exclude = NULL)
  df[[measure_var]] <- as.numeric(df[[measure_var]])
  return(df)
}

plot6_4summary.R(図6-4と図6-5)

plot6_4summary <- function(data, measurevar, groupvars) {
  formula <- as.formula(paste(measurevar, "~", paste(groupvars, collapse = " + ")))
    mean_data <- aggregate(formula, data = data, FUN = mean, na.rm = TRUE)
    se_data <- aggregate(formula, data = data, 
                       FUN = function(x) sd(x, na.rm = TRUE) / sqrt(length(na.omit(x))))
  summary_data <- merge(mean_data, se_data, by = groupvars, suffixes = c("_mean", "_se"))
  return(summary_data)
}

plot6_4ttest.R(図6-4と図6-5)

plot6_4ttest <- function(data, measure_var, group1, group2) {
  data$interaction_group <- interaction(data[[group1]], data[[group2]], sep = " | ")
  pairwise_results <- pairwise.t.test(
    data[[measure_var]],
    data$interaction_group,
    p.adjust.method = "bonferroni"
  )
  return(pairwise_results)
}

plot6_4.R(図6-4と図6-5)

plot6_4<- function(data, measure_var, title, interaction_var = NULL, show_legend = FALSE) {
  group_vars <- c("group_income")
  if (!is.null(interaction_var)) {
    group_vars <- c(group_vars, interaction_var)
    data[[interaction_var]] <- factor(data[[interaction_var]], 
                                      levels = c("与党派", "非与党派", "有党派", "無党派"))
  }
  
  df_pr <- summarySE2(data, measurevar = measure_var, groupvars = group_vars)
  df_pr$group_income <- factor(df_pr$group_income, levels = c("所得(低)", "所得(中)", "所得(高)"))
  
  mean_col <- paste0(measure_var, "_mean")
  se_col <- paste0(measure_var, "_se")
  
  if (!is.null(interaction_var)) {
    pairwise_results <- run_pairwise_tests(data, measure_var, "group_income", interaction_var)
  } else {
    pairwise_results <- pairwise.t.test(data[[measure_var]], data$group_income, p.adjust.method = "bonferroni")
  }
  
  significant_pairs <- sum(pairwise_results$p.value < 0.05, na.rm = TRUE)
  bg_color <- if (significant_pairs >= 9) "gray90" else if (significant_pairs >= 8) "gray95" else if (significant_pairs >= 7) "gray97" else "white"
  
  pd <- position_dodge(0.4)
  y_label <- if (measure_var == "socio") "社会志向" else if (measure_var == "ego") "個人志向" else measure_var
  
  p <- ggplot(df_pr, aes(x = group_income, y = .data[[mean_col]], 
                         group = !!sym(interaction_var), linetype = !!sym(interaction_var))) + 
    geom_errorbar(aes(ymin = .data[[mean_col]] - 1.96 * .data[[se_col]], 
                      ymax = .data[[mean_col]] + 1.96 * .data[[se_col]]), 
                  width = 0.2, position = pd) +
    geom_line(position = pd) +
    geom_point(position = pd, size = 3, shape = 21, fill = "white") +
    geom_text(aes(label = round(.data[[mean_col]], 2)), vjust = -1.5, size = 3.5) +
    xlab("") + ylab(y_label) + ggtitle(title) +
    theme_bw() + 
    theme(panel.background = element_rect(fill = bg_color, color = "black")) +
    scale_x_discrete(guide = guide_axis(angle = 45)) +
    ylim(min(df_pr[[mean_col]] - df_pr[[se_col]]) - 0.5, max(df_pr[[mean_col]] + df_pr[[se_col]]) + 0.5)
  
  if (!show_legend) {
    p <- p + theme(legend.position = "none")
  } else {
    p <- p + 
      labs(linetype = "党派性") + 
      theme(
        legend.position = c(0.85, 0.15),
        legend.background = element_rect(fill = "white", color = "black"),
        legend.title = element_text(size = 7),
        legend.text = element_text(size = 7)
      )
  }
  
  return(p)
}

plot6_6.R(図6-6)

plot6_6 <- function(data, measure_var, title, interaction_var = NULL, show_legend = FALSE) {
  group_vars <- c("group_income")
  if (!is.null(interaction_var)) {
    group_vars <- c(group_vars, interaction_var)
    data[[interaction_var]] <- factor(data[[interaction_var]], 
                                      levels = c("与党派", "非与党派", "有党派", "無党派"))
  }
  
  df_pr <- summarySE2(data, measurevar = measure_var, groupvars = group_vars)
  df_pr$group_income <- factor(df_pr$group_income, levels = c("所得(低)", "所得(中)", "所得(高)"))
 
  mean_col <- paste0(measure_var, "_mean")
  se_col <- paste0(measure_var, "_se")
  
  y_label <- if (measure_var == "vote_rul") {
    "与党投票"
  } else if (measure_var == "vote_op") {
    "野党投票"
  } else {
    measure_var
  }
  
  if (!is.null(interaction_var)) {
    pairwise_results <- pairwise.t.test(data[[measure_var]], data[[interaction_var]], p.adjust.method = "bonferroni")
  } else {
    pairwise_results <- pairwise.t.test(data[[measure_var]], data$group_income, p.adjust.method = "bonferroni")
  }
  
  significant_pairs <- sum(pairwise_results$p.value < 0.05, na.rm = TRUE)
  bg_color <- if (significant_pairs >= 3) "gray90" else if (significant_pairs >= 2) "gray95" else if (significant_pairs >= 1) "gray97" else "white"
  
  pd <- position_dodge(0.4)
  
  p <- ggplot(df_pr, aes(x = group_income, y = .data[[mean_col]], 
                         group = !!sym(interaction_var), linetype = !!sym(interaction_var))) + 
    geom_errorbar(aes(ymin = .data[[mean_col]] - 1.96 * .data[[se_col]], 
                      ymax = .data[[mean_col]] + 1.96 * .data[[se_col]]), 
                  width = 0.2, position = pd) +
    geom_line(position = pd) +
    geom_point(position = pd, size = 3, shape = 21, fill = "white") +
    geom_text(aes(label = round(.data[[mean_col]], 2)), vjust = -1.5, size = 3.5) +
    xlab("所得階層") + ylab(y_label) + ggtitle(title) +
    theme_bw() + 
    theme(panel.background = element_rect(fill = bg_color, color = "black")) +
    scale_x_discrete(guide = guide_axis(angle = 45)) +
    ylim(min(df_pr[[mean_col]] - df_pr[[se_col]]) - 0.5, max(df_pr[[mean_col]] + df_pr[[se_col]]) + 0.5)
  
  if (!show_legend) {
    p <- p + theme(legend.position = "none")
  } else {
    p <- p + 
      labs(linetype = "党派性") + 
      theme(
        legend.position = c(0.85, 0.15), 
        legend.background = element_rect(fill = "white", color = "black"),
        legend.title = element_text(size = 7),  
        legend.text = element_text(size = 7)  
      )
  }
  
  return(p)
}

第7章

plot7_2df.R(図7-2)

plot7_2df <- function(df, measure_var, title = "") {
  df <- df %>%
    filter(!is.na(socio)) %>%
    mutate(
      socio = case_when(
        socio == 1 ~ "かなり悪い",
        socio == 2 ~ "悪い",
        socio == 3 ~ "どちらでもない",
        socio == 4 ~ "良い",
        socio == 5 ~ "かなり良い"
      )
    )
  
  processed_df <- df %>%
    select(socio, all_of(measure_var)) %>%
    na.omit()
  
  processed_df[[measure_var]] <- as.numeric(processed_df[[measure_var]])
  
  attr(processed_df, "title") <- title
  
  return(processed_df)
}

plot7_2.R(図7-2)

plot7_2 <- function(data, measure_var, title) {
  df_pr <- summarySE(data, measurevar = measure_var, groupvars = c("socio"))
  df_pr$socio <- factor(df_pr$socio, levels = c("かなり悪い", "悪い", "どちらでもない", "良い", "かなり良い"))
  
  y_label <- if (measure_var == "vote_rul") {
    "与党投票"
  } else if (measure_var == "vote_op") {
    "野党投票"
  } else {
    measure_var
  }
  
  pairwise_results <- pairwise.t.test(data[[measure_var]], data$socio, p.adjust.method = "bonferroni")
  
  significant_pairs <- sum(pairwise_results$p.value < 0.05, na.rm = TRUE)
  
  if (significant_pairs >= 5) {
    bg_color <- "gray90" 
  } else if (significant_pairs >= 4) {
    bg_color <- "gray95"  
  } else if (significant_pairs >= 3) {
    bg_color <- "gray97" 
  } else {
    bg_color <- "white"   
  }
  
  pd <- position_dodge(0.4)
  
  
  df_pr$mean_label <- round(df_pr[[measure_var]], 2)
  
  p <- ggplot(df_pr, aes(x = socio, y = get(measure_var)), na.rm = TRUE) + 
    geom_errorbar(aes(ymin = get(measure_var) - 1.96 * se, ymax = get(measure_var) + 1.96 * se), size = 1, position = pd, width = .1, na.rm = TRUE) +
    geom_line(position = pd, na.rm = TRUE, group = 1) +
    geom_point(position = pd, size = 3, shape = 21, fill = "white") + 
    geom_text(aes(label = mean_label), vjust = -1.5, size = 3.5) +  
    xlab("") +
    ylab(y_label) +
    ggtitle(title) + 
    theme_bw() +
    theme(panel.background = element_rect(fill = bg_color, color = "black")) + 
    scale_x_discrete(guide = guide_axis(angle = 45)) +
    ylim(min(df_pr[[measure_var]] - df_pr$se) - 0.5, max(df_pr[[measure_var]] + df_pr$se) + 0.5)  
  
  return(p)
}

plot7_3df.R(図7-3)

plot7_3df <- function(df, measure_var) {
  df$socio[df$socio == 1] <- "かなり悪い"
  df$socio[df$socio == 2] <- "悪い"
  df$socio[df$socio == 3] <- "どちらでもない"
  df$socio[df$socio == 4] <- "良い"
  df$socio[df$socio == 5] <- "かなり良い"
  
  df$socio <- factor(df$socio, levels = c("かなり悪い", "悪い", "どちらでもない", "良い", "かなり良い"))
  
  df$psu_indep <- factor(df$psu_indep, levels = c(0, 1), labels = c("有党派", "無党派"), exclude = NULL)
  df$psu_rul <- factor(df$psu_rul, levels = c(0, 1), labels = c("非与党派", "与党派"), exclude = NULL)
  df$psu_op <- factor(df$psu_op, levels = c(0, 1), labels = c("与党派", "非与党派"), exclude = NULL)
  
  df[[measure_var]] <- as.numeric(df[[measure_var]])
  
  processed_df <- na.omit(df)
  
  return(processed_df)
}

plot7_3.R(図7-3)

plot7_3 <- function(data, measure_var, title, interaction_var = NULL, show_legend = FALSE) {
  group_vars <- c("socio")
  if (!is.null(interaction_var)) {
    group_vars <- c(group_vars, interaction_var)
    data[[interaction_var]] <- factor(data[[interaction_var]], 
                                      levels = c("与党派", "非与党派", "有党派", "無党派"))
  }
  
  df_pr <- summarySE2(data, measurevar = measure_var, groupvars = group_vars)
  df_pr$socio <- factor(df_pr$socio, levels = c("かなり悪い", "悪い", "どちらでもない", "良い", "かなり良い"))
  
  mean_col <- paste0(measure_var, "_mean")
  se_col <- paste0(measure_var, "_se")
  
  y_label <- if (measure_var == "vote_rul") {
    "与党投票"
  } else if (measure_var == "vote_op") {
    "野党投票"
  } else {
    measure_var
  }
  
  if (!is.null(interaction_var)) {
    pairwise_results <- pairwise.t.test(data[[measure_var]], data[[interaction_var]], p.adjust.method = "bonferroni")
  } else {
    pairwise_results <- pairwise.t.test(data[[measure_var]], data$socio, p.adjust.method = "bonferroni")
  }
  
  significant_pairs <- sum(pairwise_results$p.value < 0.05, na.rm = TRUE)
  bg_color <- if (significant_pairs >= 6) "gray90" else if (significant_pairs >= 5) "gray95" else if (significant_pairs >= 4) "gray97" else "white"
  
  pd <- position_dodge(0.4)
  
  p <- ggplot(df_pr, aes(x = socio, y = .data[[mean_col]], group = !!sym(interaction_var), linetype = !!sym(interaction_var))) + 
    geom_errorbar(aes(ymin = .data[[mean_col]] - 1.96 * .data[[se_col]], 
                      ymax = .data[[mean_col]] + 1.96 * .data[[se_col]]), 
                  width = 0.2, position = pd) +
    geom_line(position = pd) +
    geom_point(position = pd, size = 3, shape = 21, fill = "white") +
    geom_text(aes(label = round(.data[[mean_col]], 2)), vjust = -1.5, size = 3.5) +
    xlab("社会志向") + ylab(y_label) + ggtitle(title) +
    theme_bw() + 
    theme(panel.background = element_rect(fill = bg_color, color = "black")) +
    scale_x_discrete(guide = guide_axis(angle = 45)) +
    ylim(min(df_pr[[mean_col]] - df_pr[[se_col]]) - 0.5, max(df_pr[[mean_col]] + df_pr[[se_col]]) + 0.8)
  
  if (!show_legend) {
    p <- p + theme(legend.position = "none")
  } else {
    p <- p + 
      labs(linetype = "党派性") + 
      theme(
        legend.position = c(0.9, 1.1),  
        legend.background = element_rect(fill = "white", color = "black"),
        legend.title = element_text(size = 7),  
        legend.text = element_text(size = 7)  
      )
  }
  
  return(p)
}

plot7_6.R(図7-6)

plot7_6 <- function(df, dep_var) {
  df <- na.omit(df)
  
  independent_vars <- c("ego", "gender", "age", "educ", "employ", "media", "interest")
  
  formula_1st <- reformulate(c("psu_rul", "psu_op", independent_vars), response = "socio")
  first_stage <- lm(formula_1st, data = df)
  df$residuals_1st <- residuals(first_stage)
  
  if (dep_var == "vote_rul") {
    second_stage_vars <- c("psu_rul", "residuals_1st", independent_vars)
  } else if (dep_var == "vote_op") {
    second_stage_vars <- c("psu_op", "residuals_1st", independent_vars)
  }
  
  formula_2nd <- reformulate(second_stage_vars, response = dep_var)
  second_stage <- lm(formula_2nd, data = df)
  
  return(list(first_stage = tidy(first_stage), second_stage = tidy(second_stage)))
}

第8章

plot8_4.R(図8-4)

plot8_4 <- function(df, var_name, titles, my_comparisons) {
  ggplot(df, aes(x = group, y = !!rlang::sym(var_name), fill = color_assign)) +
    geom_bar(stat = "summary", fun = "mean", position = position_dodge(), color = "black") +
    geom_errorbar(stat = "summary", fun.data = "mean_se", fun.args = list(mult = 1), 
                  position = position_dodge(0.9), width = 0.25) +
    labs(y = titles[[var_name]], x = "", title = titles[[var_name]]) +
    theme_bw() +
    theme(axis.text.x = element_text(angle = 45, hjust = 1),
          plot.title = element_text(hjust = 0.5),
          legend.position = "none") +
    scale_fill_manual(values = c("darkgrey" = "darkgrey", "grey" = "grey", "lightgrey" = "lightgrey")) +
    geom_hline(yintercept = 0, linetype = "dashed", color = "gray") +
    stat_compare_means(comparisons = my_comparisons, label = "p.signif", method = "t.test",
                       label.y = c(0, 0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 1.05))
}

【補足】ologit8_exp1.R(図8-4)

ologit8_exp1 <- function(dv) {
  formula_str <- paste0("as.factor(", dv, ") ~ ", paste(iv_vars, collapse = " + "))
  mod_formula <- as.formula(formula_str)
  
  model <- polr(mod_formula, data = dat8_exp1_8, Hess = TRUE)
  
 
  tidy_res <- broom::tidy(model) %>% 
    filter(!grepl("\\|", term)) %>%
    mutate(p.value = 2 * pnorm(-abs(statistic)))
  
  tidy_res <- tidy_res %>%
    mutate(estimate = round(estimate, 3),
           std.error = round(std.error, 3),
           OR = round(exp(estimate), 3),
           OR_lower = round(exp(estimate - 1.96 * std.error), 3),
           OR_upper = round(exp(estimate + 1.96 * std.error), 3))
  
  res_coef <- sapply(indep_order, function(var) {
    row <- tidy_res %>% filter(term == var)
    if(nrow(row) == 0) return("")
    sig <- ifelse(row$p.value < 0.05, "*", "")
    sprintf("%.3f%s\n(%.3f)", row$estimate, sig, row$std.error)
  })
  res_OR <- sapply(indep_order, function(var) {
    row <- tidy_res %>% filter(term == var)
    if(nrow(row) == 0) return("")
    sig <- ifelse(row$p.value < 0.05, "*", "")
    sprintf("%.3f%s\n(%.3f, %.3f)", row$OR, sig, row$OR_lower, row$OR_upper)
  })
  
  n_mod <- nobs(model)
  LL_full <- as.numeric(logLik(model))
  null_model <- polr(as.factor(get(dv)) ~ 1, data = dat8_exp1_8, Hess = TRUE)
  LL_null <- as.numeric(logLik(null_model))
  McFadden_R2 <- round(1 - (LL_full / LL_null), 3)
  LogLR <- round(2 * (LL_full - LL_null), 3)
  summary_str <- sprintf("n=%d, R2=%.3f, LogLR=%.3f", n_mod, McFadden_R2, LogLR)
  
  res_coef <- c(res_coef, summary_str)
  res_OR <- c(res_OR, summary_str)
  var_names <- c(indep_labels, "モデルの要約")
  
  df <- data.frame(Variable = var_names,
                   coef = res_coef,
                   OR = res_OR,
                   stringsAsFactors = FALSE)
  return(df)
}

plot8_exp2sim15.R(図8-15)

plot8_exp2sim15 <- function(party_var, evaluation_name) {
  formula_str <- paste(evaluation_name, "~ income + education + age + gender +", party_var)
  zpar <- zelig(as.formula(formula_str), data = df, model = "normal", cite = "FALSE")
  
  setx_args_notrul <- list(zpar, income = 503, gender = 0, education = 4, age = 32)
  setx_args_notrul[[party_var]] <- 0
  x.notrul <- do.call(setx, setx_args_notrul)
  
  setx_args_rul <- list(zpar, income = 503, gender = 0, education = 4, age = 32)
  setx_args_rul[[party_var]] <- 1
  x.rul <- do.call(setx, setx_args_rul)
  
  s.out <- sim(zpar, x = x.notrul, x1 = x.rul)
  sim_result <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
  sim_fd <- quantile(sim_result[,1], c(0.5, .025, .975))
  return(sim_fd)
}

plot8_exp2df.R(図8-16)

plot8_exp2df <- function(data, label) {
  print(data)
  df <- data.frame("処置種類" = label, "党派" = c("与党派", "野党派", "無党派"), data)
  df$coef <- as.numeric(df$coef)
  df$low <- as.numeric(df$low)
  df$up <- as.numeric(df$up)
  return(df)
}

plot8_exp2sim16.R(図8-16)

plo8_exp2sim16 <- function(party_var, evaluation_name, article_type) {
  formula_str <- paste(evaluation_name, "~ income + education + age + gender +", party_var, "+", article_type,
                       "+", paste(party_var, article_type, sep = ":"))
  zpar <- zelig(as.formula(formula_str), df, model="normal", cite = "FALSE") 
  
  setx_args_notrul <- list(zpar, income = 503, gender = 0, education = 4, age = 32)
  setx_args_notrul[[party_var]] <- 1
  setx_args_notrul[[article_type]] <- 0
  x.notrul <- do.call(setx, setx_args_notrul)
  
  setx_args_rul <- list(zpar, income = 503, gender = 0, education = 4, age = 32)
  setx_args_rul[[party_var]] <- 1
  setx_args_rul[[article_type]] <- 1
  x.rul <- do.call(setx, setx_args_rul)
  
  s.out <- sim(zpar, x = x.notrul, x1 = x.rul)
  sim_result <- as.data.frame(s.out[["sim.out"]][["x1"]][["fd"]][[1]])
  sim_fd <- quantile(sim_result[, 1], c(0.5, .025, .975)) 
  return(sim_fd)
}

plot8_exp2.R(図8-16)

plot8_exp2 <- function(df, title) {
  df$処置種類名 <- factor(df$処置種類)
  
  df$highlight <- (df$low > 0 & df$up > 0) | (df$low < 0 & df$up < 0)
  
  ggplot(data=df, aes(y=coef, x=党派, ymin=low, ymax=up, linetype=処置種類名,
                      group=処置種類, fill=処置種類名)) +
    geom_hline(yintercept=0, color="black", size=0.5) +
    
    geom_rect(data = subset(df, highlight == TRUE),
              aes(xmin = as.numeric(党派) - 0.15, xmax = as.numeric(党派) + 0.15, ymin = low, ymax = up),
              fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
    
    geom_errorbar(size=.2, width=.1, linetype=1, color="black") +
    geom_point(size=3, shape=21, fill="white", na.rm = TRUE) +
    geom_line(na.rm = TRUE) +
    scale_y_continuous(limits=c(-2,2), breaks=c(-1.5,-1,-0.5,0,0.5,1.0,1.5,2.0)) +
    coord_cartesian(ylim=c(-2,2)) +
    xlab("党派") + ylab("記事を見た/見ない場合の評価差") +
    ggtitle(title) + theme_bw() +
    
    geom_text(data = subset(df, highlight == TRUE),
              aes(label = paste0(round(coef, 2), "\n[", round(low, 2), ",", round(up, 2), "]")),
              hjust = -0.5, size = 3.5) +
    
    theme(legend.position = c(0.1, 0.1), legend.key.size = unit(0.3, "cm"))
}

第9章

plot9_exp1hl.R(図9-4)

plot9_exp1hl <- function(df) {
  df$highlight <- ifelse(
    (df$情報の党派性 == "与党寄り" & (df$low > 0.5 | df$up < 0.5)) |
      (df$情報の党派性 == "非与党寄り" & (df$low > 0.5 | df$up < 0.5)),
    TRUE, FALSE
  )
  return(df)
}

plot9_exp1.R(図9-4)

plot9_exp1 <- function(data, x_var, y_var, group_var, linetype_var, x_label, y_label, title) {
  pd <- position_dodge(0.2)
  
  data <- plot9_exp1hl(data)
  
  ggplot(data = data, aes_string(y = y_var, x = x_var, ymin = "low", ymax = "up", 
                                 linetype = linetype_var, group = group_var)) +
    geom_hline(yintercept = 0.5, color = "black", size = 0.5) + 
    
    geom_rect(data = subset(data, highlight == TRUE),
              aes(xmin = as.numeric(as.factor(get(x_var))) - 0.15, 
                  xmax = as.numeric(as.factor(get(x_var))) + 0.15, 
                  ymin = low, ymax = up),
              fill = "grey90", alpha = 0.5, inherit.aes = FALSE) +
    
    geom_errorbar(aes(size = highlight), width = 0.1, position = pd) +
    geom_point(aes(size = highlight), shape = 21, fill = "white", position = pd) +
    geom_line(position = pd) +
    
    geom_text(data = subset(data, highlight == TRUE),
              aes(label = round(mean, 2)),
              position = pd, vjust = -1.5, size = 3.5) +
    
    scale_size_manual(values = c(`FALSE` = 0.2, `TRUE` = 0.7), guide = "none") +
    
    xlab(x_label) + ylab(y_label) + ggtitle(title) + 
    theme_bw() +
    theme(legend.position = "none") 
}

plot9_exp2bar1.R(図9-9)

plot9_exp2bar1 <- function(data, group_var, xlab_text, comparisons) {
  ggplot(data, aes_string(x = group_var, y = "quiz_score")) + 
    stat_summary(fun = mean, geom = "bar", fill = "grey", color = "black", width = 0.7,
                 position = position_dodge(width = 0.8)) +
    stat_summary(fun.data = mean_se, geom = "errorbar", width = 0.2, color = "black",
                 position = position_dodge(0.8)) +
    stat_summary(fun = mean, geom = "text", aes(label = round(..y.., 2)),
                 vjust = -0.3, size = 3, color = "black", position = position_dodge(0.8)) +
    xlab(xlab_text) +
    ylab("党派性解答スコア") +
    geom_hline(yintercept = 0, linetype = "dashed", color = "gray") +
    theme_bw() +
    theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
    stat_compare_means(comparisons = comparisons, label = "p.signif", tip.length = 0.005)
}

plot9_exp2bar2.R(図9-9)

plo9_exp2bar2 <- function(data, x_var, fill_var, xlab_text, comparisons) {
  ggplot(data, aes_string(x = x_var, y = "mean_quiz_score", fill = fill_var)) +
    geom_bar(stat = "identity", position = position_dodge(width = 0.8), 
             color = "black", width = 0.7) +
    geom_errorbar(aes(ymin = mean_quiz_score - se_quiz_score, ymax = mean_quiz_score + se_quiz_score),
                  width = 0.2, position = position_dodge(0.8)) +
    geom_text(aes(label = round(mean_quiz_score, 2)), 
              position = position_dodge(width = 0.8),
              vjust = -0.3, size = 3, color = "black") +
    xlab(xlab_text) +
    ylab("党派性解答スコア") +
    geom_hline(yintercept = 0, linetype = "dashed", color = "gray") +
    theme_bw() +
    scale_fill_grey(start = 0.8, end = 0.2, name = fill_var) +
    theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
    stat_compare_means(comparisons = comparisons, label = "p.signif", tip.length = 0.005)
}

plot9_exp2sim.R(図9-10)

plot9_exp2sim <- function(treatment_var, data, cov_vals) {
  formula_str <- paste("quiz_score ~", treatment_var, "+ income + education + age + gender")
  zmod <- zelig(as.formula(formula_str), data = data, model = "normal", cite = FALSE)
  
  x_control <- do.call(setx, c(list(zmod), cov_vals, setNames(list(0), treatment_var)))
  x_treat   <- do.call(setx, c(list(zmod), cov_vals, setNames(list(1), treatment_var)))
  
  s_out <- sim(zmod, x = x_control, x1 = x_treat)
  sim_out <- as.data.frame(s_out[["sim.out"]][["x1"]][["fd"]][[1]])
  quantiles <- quantile(sim_out[,1], c(0.5, 0.025, 0.975))
  return(quantiles)
}

plot9_exp2sim2.R(図9-10)

plot9_exp2sim2 <- function(data, outcome, 
                         base_var, treat_var, 
                         covars=c("age","gender","education","income"),
                         base_value=0, treat_value=1,
                         x_common=list(income=503, gender=0, education=4, age=32)) {
  
    int_term <- paste0(base_var, ":", treat_var)
  rhs_vars <- c(base_var, treat_var, int_term, covars)
  formula_str <- paste(outcome, "~", paste(rhs_vars, collapse=" + "))
  fmla <- as.formula(formula_str)
  
  z_out <- zelig(fmla, data=data, model="normal", cite = FALSE)
  
    x_args <- c(
    list(z_out),
    x_common,
    setNames(list( base_value ), base_var),
    setNames(list( 0 ), treat_var) 
  )
  x0 <- do.call(setx, x_args)
  
  x_args2 <- c(
    list(z_out),
    x_common,
    setNames(list( base_value ), base_var), 
    setNames(list( 1 ), treat_var)           
  )
  x1 <- do.call(setx, x_args2)
  
  s_out <- sim(z_out, x=x0, x1=x1)
  sim_df <- as.data.frame(s_out[["sim.out"]][["x1"]][["fd"]][[1]])
  
  FDq <- quantile(sim_df[,1], c(0.5, 0.025, 0.975))
  return(FDq)
}

第10章

plot10_4.R(図10-4)

plot10_4 <- function(filepath, responses, label_name) {
  raw_data <- read.qualtrics(
    filepath,
    responses = responses,
    covariates = c("Q2.1","Q2.2","Q2.4","Q2.7"), 
    respondentID = "ID",
    new.format   = FALSE
  )
  
  conj_data <- na.omit(raw_data)
  
  result_amce <- amce(
    selected ~ GDP成長率 + 完全失業率 + 物価 + 日経平均株価 + 為替レート + 長期金利,
    data         = conj_data,
    cluster      = TRUE,
    respondent.id= "respondent",
    design       = common_design,
    baseline     = baseline
  )
  
  est <- result_amce$estimates
  df_out <- data.frame(rbind(
    t(est$GDP成長率),
    t(est$完全失業率),
    t(est$物価),
    t(est$日経平均株価),
    t(est$為替レート),
    t(est$長期金利)
  ))
  
  df_out$経済指標 <- c(
    "GDP成長率:前期比上昇","GDP成長率:前期比低下",
    "失業率:前年同月比上昇","失業率:前年同月比低下",
    "物価:前年同月比上昇","物価:前年同月比低下",
    "日経平均:年初来上昇","日経平均:年初来低下",
    "為替:年初から円安","為替:年初から円高",
    "長期金利:上昇","長期金利:低下"
  )
  
  df_out$low <- df_out$AMCE - df_out$Std..Error*1.96
  df_out$up  <- df_out$AMCE + df_out$Std..Error*1.96
  
  df_out$投票選択 <- label_name
  
  return(df_out)
}

plot10_5.R(図10-5)

plot10_5 <- function(conj_data, label_party, label_vote) {
   result_amce <- amce(
    formula       = selected ~ GDP成長率 + 完全失業率 + 物価 + 日経平均株価 + 為替レート + 長期金利,
    data          = conj_data,
    cluster       = TRUE,
    respondent.id = "respondent",
    design        = common_design,
    baseline      = baseline
  )
  
  est <- result_amce$estimates
  
  df_out <- data.frame(rbind(
    t(est$GDP成長率),
    t(est$完全失業率),
    t(est$物価),
    t(est$日経平均株価),
    t(est$為替レート),
    t(est$長期金利)
  ))
  
  df_out$経済指標 <- c(
    "GDP成長率:前期比上昇","GDP成長率:前期比低下",
    "失業率:前年同月比上昇","失業率:前年同月比低下",
    "物価:前年同月比上昇","物価:前年同月比低下",
    "日経平均:年初来上昇","日経平均:年初来低下",
    "為替:年初から円安","為替:年初から円高",
    "長期金利:上昇","長期金利:低下"
  )
  
  df_out$low <- df_out$AMCE - df_out$Std..Error*1.96
  df_out$up  <- df_out$AMCE + df_out$Std..Error*1.96
  
  df_out$投票選択 <- label_vote
  df_out$党派      <- label_party
  
  return(df_out)
}

【補足】plot10_4factname.R(図10-4)

plot10_4factname <- function(facname, level) {
  faclev <- paste0(facname, ":", level)
  if (faclev %in% c(
    "長期金利:前年同期から低下",
    "為替レート:年初から円高方向",
    "日経平均株価:年初来上昇",
    "物価:前年同月比低下",
    "完全失業率:前年同月比低下",
    "GDP成長率:前期比上昇"
  )) {
    return("肯定")
  } else if (faclev %in% c(
    "長期金利:前年同期から上昇",
    "為替レート:年初から円安方向",
    "日経平均株価:年初来低下",
    "物価:前年同月比上昇",
    "完全失業率:前年同月比上昇",
    "GDP成長率:前期比低下"
  )) {
    return("否定")
  } else {
    # 変化なし
    return("現状維持")
  }
}

【補足】plot10_4emmeans.R(図10-4)

plot10_4emmeans <- function(model, factor_name) {
  emm <- emmeans(model, specs = as.formula(paste0("~ ", factor_name)))
  df_emm <- as.data.frame(emm)
  
  df_emm <- df_emm %>%
    mutate(
      conf.low  = emmean - 1.96*SE,
      conf.high = emmean + 1.96*SE
    )
  
  df_emm$highlight <- with(df_emm, (conf.low>0.5 & conf.high>0.5) | (conf.low<0.5 & conf.high<0.5))
  
  df_emm$FactorName <- factor_name
  
  
  levcol <- df_emm[[ factor_name ]]
  
  df_emm <- df_emm %>%
    mutate(Level = levcol) %>%
    select(FactorName, Level, emmean, SE, conf.low, conf.high, highlight)
  
  return(df_emm)
}

【補足】plot10_4makedf.R(図10-4)

plot10_4makedf <- function(model) {
  df_gdp    <- plot10_4emmeans(model, "GDP成長率")
  df_unem   <- plot10_4emmeans(model, "完全失業率")
  df_cpi    <- plot10_4emmeans(model, "物価")
  df_nikkei <- plot10_4emmeans(model, "日経平均株価")
  df_fx     <- plot10_4emmeans(model, "為替レート")
  df_ir     <- plot10_4emmeans(model, "長期金利")
  df_all <- dplyr::bind_rows(df_ir, df_fx, df_nikkei, df_cpi, df_unem, df_gdp )
  
  df_all <- df_all %>%
    rowwise() %>%
    mutate(
      category = plot10_4factname(FactorName, Level)
    ) %>%
    ungroup()
  
  df_all <- df_all %>%
    mutate(
      facIndex = match(FactorName, factor_levels),
      offset   = case_when(
        category=="肯定" ~ +0.2,
        category=="否定" ~ -0.2,
        TRUE             ~  0
      ),
      yPos = facIndex + offset
    )
  return(df_all)
}

【補足】plot10_4mm.R(図10-4)

plot10_4mm <- function(df_all, title_str="") {
  ggplot(df_all, aes(x=emmean, y=yPos, xmin=conf.low, xmax=conf.high)) +
    geom_vline(xintercept=0.5, linetype="dashed", color="gray40") +
    geom_errorbarh(height=0.08, aes(linetype=category), color="black") +
    geom_point(size=3, aes(shape=category), fill="white", color="black") +
    scale_y_continuous(
      name="経済状況",
      breaks=1:length(factor_levels),
      labels=factor_levels,
      limits=c(0.5, length(factor_levels)+0.5)
    ) +
    xlab("限界平均") +
    theme_bw() +
    ggtitle(title_str) +
    scale_shape_manual(values=c("肯定"=21,"否定"=22,"現状維持"=24)) +
    scale_linetype_manual(values=c("肯定"="solid","否定"="dotted","現状維持"="longdash")) +
    theme(
      legend.title=element_blank(),
      legend.position="right",
      axis.text=element_text(size=10,color="black"),
      axis.title=element_text(face="bold"),
      plot.title=element_text(face="bold",hjust=0.5)
    )+ 
    theme(text = element_text(family = "jpfont")) 
}

【補足】plot10_5makedf.R(図10-5)

plot10_5makedf <- function(df_subset, 
                           label_party = "", 
                           label_vote  = "") {
 
  mod <- lm(
    selected ~ GDP成長率 + 完全失業率 + 物価 + 日経平均株価 + 為替レート + 長期金利,
    data = df_subset
  )
  
  factor_names  <- c("GDP成長率","完全失業率","物価","日経平均株価","為替レート","長期金利")
  factor_labels <- factor_names 
  
  get_emm_one <- function(f_name, f_label) {
    emm  <- emmeans(mod, specs = as.formula(paste0("~ ", f_name)))
    df_e <- as.data.frame(emm) %>%
      mutate(
        conf.low  = emmean - 1.96 * SE,
        conf.high = emmean + 1.96 * SE,
        highlight = (conf.low>0 & conf.high>0) | (conf.low<0 & conf.high<0),
        FactorName = f_label,
        Level      = .data[[f_name]]  
      ) %>%
      select(FactorName, Level, emmean, SE, conf.low, conf.high, highlight)
    df_e
  }
  
  mm_list <- lapply(seq_along(factor_names), function(i) {
    get_emm_one(factor_names[i], factor_labels[i])
  })
  
  df_mm <- do.call(rbind, mm_list)
  
  df_mm <- df_mm %>%
    mutate(
      party_label = label_party,
      vote_label  = label_vote
    )
  
  return(df_mm)
}

【補足】plot10_5mm.R(図10-5)

plot10_5mm <- function(df_plot, factor_levels, title_str = "") {
  df_plot2 <- df_plot %>%
    mutate(
      facIndex = match(FactorName, factor_levels),
      
      offset_cat = case_when(
        category == "肯定"      ~  0.15,
        category == "否定"      ~ -0.15,
        TRUE                    ~  0    
      ),
      
      offset_party = case_when(
        party_label == "与党派"  ~  0.10,
        party_label == "無党派"  ~ -0.10,
        TRUE                    ~  0.00 
      ),
      
      yPos = facIndex + offset_cat + offset_party
    )
  
  ggplot(df_plot2, aes(
    x     = emmean,
    y     = yPos,
    xmin  = conf.low,
    xmax  = conf.high,
    color = party_label,
    shape = category,
    linetype = category,
    group = interaction(party_label, category)
  )) +
    geom_vline(xintercept = 0.5, linetype="dashed", color="gray40") +
    
    geom_errorbarh(height=0.15, size=0.5) +
    geom_point(size=3, fill="white") +
    
    scale_y_continuous(
      name   = "経済指標(上→下の順)",
      breaks = seq_along(factor_levels),
      labels = factor_levels,
      limits = c(0.5, length(factor_levels) + 0.5)
    ) +
    
    xlab("marginal means") +
    theme_bw() +
    ggtitle(title_str) +
    
    scale_shape_manual(values = c("肯定"=21, "否定"=22, "現状維持"=24)) +
    scale_linetype_manual(values = c("肯定"="solid", "否定"="dotted", "現状維持"="longdash")) +
    scale_color_manual(values = c("与党派"="red","野党派"="blue","無党派"="gray")) +
    
    theme(
      legend.title    = element_blank(),
      legend.position = "right",
      axis.text       = element_text(size=10, color="black"),
      axis.title      = element_text(face="bold"),
      plot.title      = element_text(face="bold", hjust=0.5)
    ) + 
    theme(text = element_text(family = "jpfont")) 
}