RでTALIS2018

2019年6月19日にTALIS(国際教員指導環境調査)2018年調査結果が公表されました。

TALIS - The OECD Teaching and Learning International Survey (OECD)
http://www.oecd.org/education/talis/


「OECD国際教員指導環境調査(TALIS)2018調査結果」(文部科学省)
http://www.mext.go.jp/b_menu/toukei/data/Others/1349189.htm


「OECD 国際教員指導環境調査(TALIS) 2018年報告書について」(国立教育政策研究所)
https://www.nier.go.jp/kenkyukikaku/talis/index.html


『教員環境の国際比較 OECD国際教員指導環境調査(TALIS)2018報告書 学び続ける教員と校長』(ぎょうせい)
https://shop.gyosei.jp/products/detail/10041

調査結果についての概要や分析は,上記のサイトから資料や報告書を入手していただくとして,今回はOECDが提供している調査回答データをRで利用しようというのが本題。以前,PISA2015で挑戦したことをTALIS2018でもやってみようということになります。(RでPISA2015RでPISA2015〈その2〉RでPISA2015〈グラフ〉

OECDのTALIS 2018サイトで公開されているデータはこちら

TALIS 2018 Data
http://www.oecd.org/education/talis/talis-2018-data.htm

それぞれの統計処理パッケージ(SAS, SPSS, STATA)用のデータが配布されています。とりあえずSPSS用のファイルをダウンロードします。

今回は「SPSS_international.zip」を先に覗いてみることにしましょう。

校長
ACGINTT3.sav(小学校) 
BCGINTT3.sav(中学校)
CCGINTT3.sav(高等学校)
教員
ATGINTT3.sav(小学校)
BTGINTT3.sav(中学校)
CTGINTT3.sav(高等学校)

どのファイルが何に該当するのか説明が添えられていないので,中身から判断します。

質問文を参照するためには質問紙データをダウンロードします。

TALIS 2018 questionnaires
http://www.oecd.org/education/school/talis2018questionnaires.htm

国立教育政策研究所で公開されている日本語版や各国の質問用紙は,OECDの国際版をベースに作成されているので問題番号の対応は自分で調べます。

とりあえず,小学校教員用質問紙「ATGINTT3」の問題番号と英語・日本語の質問文対応データを作成しましたのでこれを使います。それから国名も日本語の方がいいでしょう。

ATGINTT3 質問文データ
http://www.edufolder.jp/files/talis2018/ATGINTT3_Q.csv

国別コードと国名データ
http://www.edufolder.jp/files/talis2018/ISO3166.csv

小学校教員用質問紙「ATGINTT3」用のみですが,最低限必要なデータは揃いました。

本来ならば,質問項目に対応した回答項目データも作成して,回答も日本語で分かりやすく表示できるとよいのですが,データ作成の手間の問題なので,とりあえず後に回します。

さて,RとR Studioをインストールしておきます。これは以前のPISA2015での記録を参照してください。

今回も最初に一度読み込むための「talis2018_base.R」と質問グラフを生成する毎に実行する「talis2018_script.R」という2つのスクリプトファイルに分けて作成しました。

質問項目ごとに回答の数が異なるので,毎度修正しなければならないという課題は残っていますが,とりあえず動作すると思います。

「talis2018_base.R」

# talis2018_base.R
# For TALIS2018
# K.RIN
#

#ライブラリ読み込み
library(readr)
library(tidyverse)
library(plyr)
library(haven)

#データファイル読み込み
ATGINTT3 <- read_sav("ATGINTT3.sav")

question_items <- read_csv("ATGINTT3_Q.csv", col_names = TRUE, col_types = list(col_character(), col_character(), col_character()))

country_code <- read_csv("ISO3166.csv", col_names = TRUE, col_types = list(col_character(), col_character(), col_character(), col_character()))

「talis2018_script.R」

# talis2018_script.R
# For TALIS2018
# K.RIN
#
# ★設定項目(★マーク)
# ・質問ID(「selected_question = " "」の部分)
# ・表示順(「order_setting = 1」の部分)
# ・表示順の組合わせ(「mutate('list_order' = `1`)」の部分)

library(plyr)
library(tidyverse)

#★質問番号
selected_question = "TT3G55I"

#★表示順(降順1,昇順-1)
order_setting = 1

#ラベル
y_label <- "パーセント %"
x_label <- "国"
legend_label <- "回答"

#質問文データから質問番号に該当する質問文を抽出
if (is.na(question_items$ja[grep(selected_question, question_items$q_no, value = FALSE, fixed = FALSE)][[1]])) {
q_title <- paste("【", selected_question,"】")
} else { #質問文が空欄でなければ…
q_title <- paste("【", selected_question,"】", question_items$ja[grep(selected_question, question_items$q_no, value = FALSE, fixed = FALSE)][[1]])
}

#回答データ抽出
stu_tmp <- subset(ATGINTT3, ATGINTT3[[selected_question]] != "NaN") #無回答を除く(質問してない国もあるため)
data_ans <- table(stu_tmp[["CNTRY"]],stu_tmp[[selected_question]]) #質問番号のデータを抽出

ans_df <- as_tibble(data_ans,validate = FALSE) #df(データフレーム)へ変換
colnames(ans_df) <- c("CNT", "answer", "count") #dfの列ラベル設定
ans_wide <- spread(ans_df, answer, count) #横長dfへ変換

#行番号をデータに変換して列として追加
#★グラフ表示順を決める回答項目の数値合計を列として追加[ +`2`+`3`+`4`+`5`]
ans_wide <- ans_wide %>% rownames_to_column('num') %>% mutate('list_order' = `2` + `3`)

#num列の数字を文字から数値にモード変換
mode(ans_wide$num) <- "integer"
typeof(ans_wide$num)

#国コードをもとに国名をcountry_name列として追加
ans_wide <- ddply(ans_wide, "CNT", transform, country_name = country_code$Name_ja[grep(CNT, country_code$Alpha3)])
#列ラベルの設定
colnames(ans_wide) <- c("num", "CNT", "1", "2", "3", "list_order", "country_name") #※回答項目3つの場合(, "4")

#縦長dfに変換
ans_df <- gather(ans_wide, answer,count,-num,-CNT,-list_order,-country_name)

#国コードと回答で並べ替え
ans_df <- arrange(ans_df, desc(CNT), desc(answer))

#パーセント計算(描画計算用パーセント)
ans_df <- ddply(ans_df, "CNT", transform, percent = count / sum(count) * 100, 0.1)
#小数点以下1桁処理(表示用パーセント)
country_ans <- ddply(ans_df, "CNT", transform, percent_rounded = round_any(count / sum(count) * 100, 0.1))
#数値合計した分のパーセント数値を計算(表示順序用パーセント)
country_ans <- ddply(country_ans, "CNT", transform, list_percent_order = round_any(list_order / sum(count) * 100 * order_setting, 0.1))


#ラベル位置計算
country_ans <- ddply(country_ans, "CNT", transform, percent_label_y = cumsum(percent)-0.5*percent)

#フォント準備(Mac用)
#
quartzFonts(HiraKaku = quartzFont(rep("HiraginoSans-W3", 4)))
par(family = "HiraKaku")

#グラフ描画準備
#
graph <- ggplot(country_ans, aes(x = reorder(country_name, list_percent_order), y = percent, fill = answer)) + 
ggtitle(sprintf("%s", q_title)) + #タイトル
ylab(y_label) + #国ラベル
xlab(x_label) + #パーセントラベル
coord_flip(expand = FALSE) + 
geom_bar(stat = "identity", position='stack') + 
geom_text(aes(y = percent_label_y, 
label = paste(format(percent_rounded, nsmall = 1),"")), color = "white", size = 4) + #データラベル
scale_y_reverse(breaks = c(100.0,75.0,50.0,25.0,0.0), 
labels = c("0%","25%","50%","75%","100%")) + #横軸
scale_color_manual(values = rainbow(7)) + #カラー
theme_bw() + 
theme(plot.margin = margin(1, 1, 1, 1, "cm"),
plot.title = element_text(family = "HiraKaku", size = 10), 
plot.caption = element_text(family = "HiraKaku", size = 10),
legend.title = element_text(family = "HiraKaku", size = 10), 
legend.text = element_text(family = "HiraKaku", size = 7), 
axis.title = element_text(family = "HiraKaku", size = 9), 
axis.title.y = element_text(angle = 0, vjust = 0.5), 
axis.text.x = element_text(family = "HiraKaku", size = 9), 
axis.text.y = element_text(family = "HiraKaku", size = 10))

print(graph) #グラフ描画

以上で「Plots」ウインドウにグラフが描画されると思います。

また詳細は〈その2〉を予定しています。