SNAGeek

Sociologically Technological, and Technologically Sociological

Rでtibble(data.frame)からネストされたjsonを出力する

tibble to nested json などで検索するといろいろな方法出てきますが、一番スマートなのは tidyr::nest() でネストしたtibbleを jsonlite::toJSON()jsonに変換するやり方かと思います。

セッション情報

諸事情あってRStudioDesktopで動かしています。

> sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=Japanese_Japan.932  LC_CTYPE=Japanese_Japan.932    LC_MONETARY=Japanese_Japan.932 LC_NUMERIC=C                  
[5] LC_TIME=Japanese_Japan.932    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] compiler_4.0.2 tools_4.0.2    yaml_2.2.1    
> 

データ読み込み

データは MASS パッケージに同梱されている Cars93 データの一部を用います。

> library(tidyverse)
> library(jsonlite)

 次のパッケージを付け加えます: ‘jsonlite’ 

 以下のオブジェクトは ‘package:purrr’ からマスクされています: 

     flatten 

> 
> car_data <- MASS::Cars93 %>%
+   as_tibble %>%
+   select(1:5)
> car_data
# A tibble: 93 x 5
   Manufacturer Model      Type    Min.Price Price
   <fct>        <fct>      <fct>       <dbl> <dbl>
 1 Acura        Integra    Small        12.9  15.9
 2 Acura        Legend     Midsize      29.2  33.9
 3 Audi         90         Compact      25.9  29.1
 4 Audi         100        Midsize      30.8  37.7
 5 BMW          535i       Midsize      23.7  30  
 6 Buick        Century    Midsize      14.2  15.7
 7 Buick        LeSabre    Large        19.9  20.8
 8 Buick        Roadmaster Large        22.6  23.7
 9 Buick        Riviera    Midsize      26.3  26.3
10 Cadillac     DeVille    Large        33    34.7
# ... with 83 more rows

tibbleそのまま出力

素直に toJSON() すると、一つの行の各要素が同じ階層内に格納された形で出力されます。

> car_data %>%
+   toJSON(pretty = TRUE)
[
  {
    "Manufacturer": "Acura",
    "Model": "Integra",
    "Type": "Small",
    "Min.Price": 12.9,
    "Price": 15.9
  },
  {
    "Manufacturer": "Acura",
    "Model": "Legend",
    "Type": "Midsize",
    "Min.Price": 29.2,
    "Price": 33.9
  },
...

1段ネストされたjsonを出力

ネストされたjsonを出力するためには、一度何らかの変数のセットで他の変数をネストしてから toJSON() します。 例えば、 Manufacturer で他の変数をネストしてみます。

> car_data %>%
+   group_by(Manufacturer) %>%
+   nest() %>%
+   toJSON(pretty = TRUE)
[
  {
    "Manufacturer": "Acura",
    "data": [
      {
        "Model": "Integra",
        "Type": "Small",
        "Min.Price": 12.9,
        "Price": 15.9
      },
      {
        "Model": "Legend",
        "Type": "Midsize",
        "Min.Price": 29.2,
        "Price": 33.9
      }
    ]
  },
  {
    "Manufacturer": "Audi",
    "data": [
      {
        "Model": "90",
        "Type": "Compact",
        "Min.Price": 25.9,
        "Price": 29.1
      },
      {
        "Model": "100",
        "Type": "Midsize",
        "Min.Price": 30.8,
        "Price": 37.7
      }
    ]
  },
...

ManufacturerType の2変数でネストすると、

> car_data %>%
+   group_by(Manufacturer,Type) %>%
+   nest() %>%
+   toJSON(pretty = TRUE)
[
  {
    "Manufacturer": "Acura",
    "Type": "Small",
    "data": [
      {
        "Model": "Integra",
        "Min.Price": 12.9,
        "Price": 15.9
      }
    ]
  },
  {
    "Manufacturer": "Acura",
    "Type": "Midsize",
    "data": [
      {
        "Model": "Legend",
        "Min.Price": 29.2,
        "Price": 33.9
      }
    ]
  },

2段ネストされたjsonを出力

次は、ネストされたjsonの中で更にネストされたjsonを出力します。 この場合は, purrr:map() を使うのが便利です。 例えば、Manufacturer の内部で Type によって更にネストしてみます。

> car_data %>%
+   group_by(Manufacturer) %>%
+   nest() %>%
+   mutate(data = map(data,group_by,Type) %>%
+            map(nest)) %>%
+   toJSON(pretty = TRUE)
[
  {
    "Manufacturer": "Acura",
    "data": [
      {
        "Type": "Small",
        "data": [
          {
            "Model": "Integra",
            "Min.Price": 12.9,
            "Price": 15.9
          }
        ]
      },
      {
        "Type": "Midsize",
        "data": [
          {
            "Model": "Legend",
            "Min.Price": 29.2,
            "Price": 33.9
          }
        ]
      }
    ]
  },
  {
    "Manufacturer": "Audi",
    "data": [
      {
        "Type": "Compact",
        "data": [
          {
            "Model": "90",
            "Min.Price": 25.9,
            "Price": 29.1
          }
        ]
      },
      {
        "Type": "Midsize",
        "data": [
          {
            "Model": "100",
            "Min.Price": 30.8,
            "Price": 37.7
          }
        ]
      }
    ]
  },
...

Enjoy!

働きながら大学院生もやっていく(中間報告)

この記事はSansan Advent Calendar 2020 4日目の記事です。 adventar.org

はじめに

 民間企業で働きつつ大学院生としての活動を本格的に再開させてから、そろそろ1年が経過しようとしています。今回の記事ではその簡単な振り返りと、採用したサービスや取り入れた生活習慣などを紹介します。主眼にあるのは、ものすごく高い生産性で研究をするためのライフハック、ではなく、持続可能でかつストレスの少ないような研究の続け方です。誰かにとって参考になれば嬉しいです。

 もちろん、人それぞれ学問領域や大学院の制度、労働環境は異なる部分があるかと思います。私は社会学専攻であり、なかでも定量的なアプローチを採用することが多く、かつ、研究のためのデータは既存の大規模社会調査データや、修士のときに収集したデータを用いています。そのため、データ収集のために特殊な機械や施設での実験が必要な方や、フィールドワークを行っている方にとっては、仕事と研究の両立という観点ではあまり参考にならないかもしれません。そうした前提に立ってお読みいただければ幸いです。

経緯

 大学院博士課程に復学したのは、今年(2020年)の4月です。博士課程の1年目が終了したタイミングで民間企業に就職(転職)した後、2年間の休学を経ての復学となりました。就職までの経緯については、過去に公開した以下のエントリで紹介しています。

meana0.hatenablog.com

 就職してから、それなりに充実した生活を送れていたのですが、ずっと「論文を書いていない」「学位を取っていない」ことの後ろめたさが残っていました。こうした心的負荷は次第に大きくなっていき、もはや無視できるレベルではないと感じたため、20代の残り時間で論文投稿や博士論文執筆に取り組むことを決意しました。

 入社から1年半ほどが経過してから、人事評価など、折りを見て上司に復学する可能性を伝えていました。復学前から大学院のゼミには仕事終わりに週1回出席し、途中で挫折していた修士論文の投稿論文化を進めたりと、ゆっくりと大学院生活に向けたリハビリを行いました。私が通っている大学院は社会人用の夜間コースではなく、課程博士のコースなのですが、ゼミがたまたま6限に開講されていたため、定時上がりをすれば参加することができました。

 いきなり復学するのではなく、このようなバッファの期間を作ったことで、会社側と調整する時間を確保しつつ、「自分が働きながら本当に研究活動を続けていけるかどうか」を正確に判断することができました。最終的には、人事と交渉しながら、仕事を週1日休みの時短勤務にしてもらい、正式に復学しました(勤務先の企業には感謝してしきれません)。

研究・博士論文について

 ちなみに、大学院博士課程では社会学を専攻しており、主に「趣味やオンラインメディアと社会ネットワークにおける同類結合の関係性」について研究しています。博士論文では、簡単に言うと「趣味やオンラインメディアは同類結合を緩和する可能性がある」という主張をする予定です。審査に通った暁には、公開すること機会があるかもしれません。

 他分野では博士論文提出の要件として投稿論文2~3本の掲載を課している大学院も多いようですが、社会学の業界でそのような風潮は稀薄で、ほとんどの場合、投稿論文を集めたベストアルバムというよりも、重厚長大大河ドラマのような博士論文が要求されます。

 したがって、博士号取得のために論文投稿は必須のステップではありません。しかしながら、長きにわたる博士論文全体のマイルストーン的な意味合いや、各章で行っている先行研究の整理や分析を洗練させるために査読という外部システムが有用であることから、各章の内容はできるだけ論文化しようとしています。ちなみに、社会学における博士論文の書き方については、以下のnoteが非常に参考になります。

復学後にやったこと

note.com

 2020年に研究関連で行ったことを以下にまとめました。

1月 | 修士論文の内容を再構成して投稿
2月 | 博士論文第3章にあたる論文を書く
3月 | 査読結果(ラウンド1)が帰ってくる
4月 (時短勤務に変更) | 査読対応 → 再投稿
5月 | 博士論文第3章にあたる論文を書く
6月 | 査読結果(ラウンド2)が帰ってくる
7月 | 査読対応 → 再投稿
8月 | 博士論文全体の構成を検討する作業
9月 | 査読結果(ラウンド3)が帰ってくる → 掲載決定
10月 | 博士論文第3章にあたる論文を書く
11月 | 博士論文中間発表
12月 | (博士論文第3章にあたる論文を投稿予定)

 年始は3本の論文投稿(+研究ノート1本)を目標としていましたが、現実はなかなか厳しく、1本投稿(出版)と頑張ればもう1本投稿できるかできないか、という結果となってしまいました。こうして振り返ってみると、査読対応にかなりの時間が奪われていることがわかりますね…。論文投稿から出版までの過程については、後述しようかと思います。ちなみに、以下のページから拙著を読むことができますので、関心のある方はチェックしてみていただけると幸いです。

www.exeley.com

 前向きに捉えると査読対応の合間に博士論文全体の構成を固めることができたので、今後1年間はその構成を具体化できるかの勝負になってくるかと思います。

研究を続け(させ)るためにやったこと

 ここからは、この1年間、働きながら大学院での研究活動を続けるため、あるいは、自分に研究活動を続けさせるために何が必要だと思ったか、そのためにどんなサービスを採用したか、どんな生活習慣を取り入れたかについて書きます。結局のところ、自分の場合は「やる気を(再)燃焼させる」「タスクを細分化する」「生活リズムを崩さない」「好きなことを捨てない」という4点に収斂するかと思います。

やる気を(再)燃焼させる

 研究のモチベーション管理について、実を言うと私の場合は「研究が楽しくて仕方がない!」というモードははるか昔に通り過ぎてしまっています。「この研究テーマは自分以外には取り組んでいないものなので、完遂する必要がある」という使命感を持っていることは事実ですが、同時に、自分の中で燃え殻のようなやる気が消えないよう、必死に空気を送り込み、火種を絶やさないようにしているのが現状です。

 私の場合は、「やる気があるから作業する」ということはほとんどなく、「作業するからやる気が出てくる」というケースがほとんどです。一度作業を始めると、色々とやるべきことが見えてきて、結局長時間作業を継続することができます。したがって、半強制的にまとまった時間を作業する習慣を作ることが重要になります。

 そこで、ポモドーロ・テクニック(以下ポモと表記)を使っています。簡単に言うと、25分集中+5分休憩のサイクルを繰り返すことを指します。1ポモでエンジンが入ることもあれば、5ポモやってからやっとやる気が出てくる、ということもあります 。研究室の後輩がポモドーロ・テクニックについての秀逸な解説記事を書いているので、一読をおすすめします。

note.com

 ポモをするためのタイマーアプリは様々あるのですが、私はForestというアプリをスマートフォンとPCに入れています。Forestはポモのためのアプリではなく、スマホ依存を解消するためのアプリですが、優秀なポモタイマーとして使うこともできます。Forestの機能はいたってシンプルです。まず時間を決めます。ボタンを押すと木が育ち、決められた時間の間にTwitterを開いたりすると、木が枯れます(悲しい)。たったこれだけですが、n日連続で木を植え続けると称号が獲得できたり、植えられる木の種類が増えていき、作業する習慣が根付いていきます(木だけに)。

play.google.com

 Forestは、インセンティブの設計が絶妙です。単なるタイマーだと蓄積するインセンティブがありませんが、以下の画像のように作業した分だけ森が広がっていく様を確認すると、ホクホクした気分になります。作業をやめた時のペナルティが「木が枯れる」なのも良い塩梅だと思います。仮に、途中でやめると「キャラクターが死ぬ」だとあまりにかわいそうな気持ちになってしまいます。また、Chrome拡張を入れるとTweetDeckやFacebookなどのページが強制的に黒くマスキングされて見えないようになる(アーキテクチャによる行為の制限!)のも高評価ポイントです。

 下の画像は、緊急事態宣言化で毎日在宅勤務していた時の植樹記録です。通勤時間がないので、その分研究に時間が使えています。働きつつここまで作業できているのは、少しだけ自分を褒めてあげてもいいかなと思っています。このように、研究に費やした時間を可視化することは、「自分はやれている」という自己効力感を得るメリットがあります。

f:id:meana0:20201204111227p:plain

タスクを細分化する

 働きながら論文を書くとなると、12時間など大きな連続領域を確保することが難しくなるため、小さなまとまった時間を確実に積み上げていくことが重要になります。そこで、タスクのほうも小さくするのがベターです。

 仕事と研究どちらでもタスクの管理はNotionで行っています。下の画像は、査読コメントから、約100個の作業内容に落とし込んだテーブルと、現在の研究活動のタスクボードです。査読コメントのテーブル場合、一つ一つの作業をタイプ別に分類しています。例えば表現に関するものであればExpressionというタグを、分析に関するものであればAnalysisというタグをつけます。タグは同時に作業の難易度も表しているので、「明日は残業するかもしれないから、Expressionの修正だけ行おう」というようなタスクの優先度をつけることもできます。タスクボードは、今書いている論文などで必要な作業の進捗をTodo, Doing, Doneに分けて管理するものです。これは自分で作ったものではなく、Notionの既存のテンプレートを利用しています。タスク管理が主な目的ですが、Doneの列にタスクが積み上がっていくと、達成感と同時に、Forestアプリの森と同じように、「やれている」という自己効力感を得ることができます。

f:id:meana0:20201204171504p:plain

f:id:meana0:20201204105637p:plain

 最近は「あえてやり残しを作る」のも重要だと感じています。つまり、常にTodoの部分にタスクがある状態を作ることです。自分の癖として、「何をやらなければならないか」が明瞭でない状態に、最も机に向かう気力がないという経験則があります。論文を書いていると、作業をしているうちに新たな作業の必要性が明らかになってくる、ということがよくあります。そうしたタスクの連鎖をコントロールするためにも、常に向き合うべきタスクがある、という状態に置くようにしています。

生活リズムを崩さない

 研究生活の基盤を形づくるのが生活リズムです。私の体質的に、油断すると睡眠リズムは一気に崩れてしまうので、これは本当に大事です。具体的には下記のエントリで書いていることを引き続き実践しています。現代文明の力を駆使することと、休日に寝すぎないのがコツです。ちなみに先日、Nature RemoのAWS障害で会社に遅刻しかけました。

meana0.hatenablog.com

好きなことを捨てない

 また自分語りになってしまいますが、私には、抱えきれないほど多くの趣味があります。早朝に起きてモノレールに乗って野鳥観察をしたと思えば、部屋にこもってスプラトゥーン2をしたり、夜は千駄木で延々と野良猫を探したり…など、きわめて複層的で、焦点の定まらない生活を送っています。

 学生の頃はけん玉、フリースタイルラップ(の真似事)、料理、Webスクレイピング、大学の施設で無料で映画鑑賞、自転車で23区内のサブウェイを全部回ってどこのポテトが一番美味しいかを検証する…などの安価に楽しめるアクティビティに興じていましたが、定収のある生活を始めてからは、ますます好きな趣味が増えてしまいました。自分が1ヶ月後どんなことに耽溺するか、まったく予想できません。

 「いかに研究以外のことを考えるか」で悩む人も多いようですが、自分の場合は、「絡まりきった趣味生活の中に、いかにして研究活動をねじ込むか」が主な課題になります。そこでForestの活用やタスクの細分化などが有効となるわけです。

 とは言いつつも、復学する上で、多数の趣味があることは足枷になるどころか、むしろ背中を押してくれる要因になったと感じています。どういうことかというと、「これだけ好きなものがあるのだから、いつでも戻ってこれる」という謎の自信がつくためです。

 ライムスターの宇多丸さんは、先日話題になった記事でこのように語っています。

getnavi.jp

自分が好きなものをわかってる人は勝ち組ですよ、それだけで。だって、それで確実に楽しくなるんだもん。もちろん、人生いろんな局面が来るから、そこが灰色に見えだすときもある。そんなときに、いろんなチャンネルを持っているといいんですよね。『最近、オレなんか音楽にはピンとこねえな』ってときも、今はゲームなんです、今は映画なんです、今は酒なんですで別にいいんです。美味しい飯とかでもいいじゃんって

 宇多丸さんの発言とは少し離れてしまうかもしれませんが、好きなものに囲まれていると、自分の場合は「そしたら、ちょっとつらいこともやってみようか」という気分になります。悪く言えば「現実逃避」ですが、宿命的につらい時、逃避できる何かの存在は、時として現実と向き合うための勇気を与えてくれます。

さいごに

 「社会人大学院生」「二足のわらじを履く」と聞くと、ストイックな人物像や過酷な生活を連想します。「あらゆる余暇時間を削って研究に没頭する」のが理想だとは思いますが、人生は長く、来年学位を取らなければ死ぬわけでもないので、最近では適度に肩の力を抜きつつやっていけばいいと思うようになりました。振り返ってみると、習慣化して、コツコツ積み上げていくことが大事という極めてシンプルな結論に辿り着きます。小学生の時に気付きたかった事実です。

 来年もどうぞよろしくお願いいたします。

社会的不平等は社会的機能ではない――Tumin (1953)のメモ

※大学院ゼミのレジュメ用にまとめたものです。

Tumin, M. M. (1953). Some principles of stratification: A critical analysis. American Sociological Review, 18(4), 387-394.

  • 社会的不平等の遍在性(ubiquity)と古さ(antiquity)は、そこには必然的かつ積極的に機能する何かがあるに違いないという仮定を生み出している。
  • その最も端的な例は、Kingsley DavisとWilbert Mooreによる有名な論文 "Some Principles of Stratification"にある(Davis and Moore 1945)。その主張内容は、以下の命題に集約可能。
    1. いかなる社会においても、ある特定のポジションは他のポジションよりも機能的に重要であり、そのパフォーマンスのために特別な技能(skills)を必要とする。
    2. いかなる社会においても、これらのポジションにふさわしい技能に訓練することができる才能(talents)を持っているのは、限られた数の個人だけである。
    3. 才能を技能に変換するためには、訓練を受ける者が何らかの犠牲を払う訓練期間が必要である。
    4. 才能のある人物がこれらの犠牲を払い、訓練を受けるように誘導するためには、彼らの将来のポジションは、社会が提供しなければならない希少で不均衡な報酬への特権的かつ不釣り合いなアクセスという、差別的(differential)な価値を持たせなければならない。
    5. これらの希少な報酬や望ましい報酬は、そのポジションに付随する権利や特権からなり、 滋養と快適さ、ユーモアと気晴らし、自尊心と自我の拡大に寄与するものに分類することができる。
    6. このような社会の基本的な報酬へのアクセスの差が、様々な階層(strata)が獲得する威信と尊敬の差を生むことになるのである。これは、権利や特権とともに、制度化された社会的不平等、すなわち階層化(stratification)を構成しているといえる。
    7. したがって、希少財や希望する財の量や、それらが受ける威信や尊敬の量において、異なる階層間の社会的不平等は、いかなる社会においても、積極的に機能するものであり、必然的なものである。

以下、それぞれの命題について批判的な検討を行っていく。

1. いかなる社会においても、ある特定のポジションは他の地位よりも機能的に重要であり、そのパフォーマンスのために特別な技能(skills)を必要とする。

  • 「機能的に重要(functionally important)」という語の不明瞭さ
    • 生存価(survival value)の最小値と最大値の問題と、これらの用語に与えられる可能性のある経験的な支持物(referents)があるか。
    • 任意の時点での現状は、現状に存在するすべてのものがそれ以上でもそれ以下でもないので、このような命題はトートロジーであるかどうか。
    • どのような行為や構造をどれくらいの重みで機能に貢献するものかを見積っているのか。
  • 機能性の重要度が暗黙の価値選好によって行われている可能性
    • どの職業であれ、経営者はモチベーションの問題には短期的に向きわなければならない。
    • 一部の、交渉力(bargaining power)が高い職種もあるが、それは結果として得られたものにすぎない。
  • 誘引や報酬は、数ある動機付けシステムの中の多くのバリエーションの一つにすぎない。

2. いかなる社会においても、これらのポジションにふさわしい技能に訓練することができる才能(talents)を持っているのは、限られた数の個人だけである。

  • 人口の中に存在する才能の存在と、その知識に対する疑問
    • 社会が厳格に階層化されればされるほど、その社会がメンバーの才能についての新しい事実を発見する機会は少なくなる。
      • e.g. 訓練へのアクセスが親の富に依存し、富の分配が異なる社会では、人口の大部分が自分の才能を発見する機会すら奪われてしまう可能性
  • ある世代における報酬の不平等な分配は、後続の世代におけるモチベーションの不平等な分配をもたらす傾向がある。
  • エリートは訓練や採用を制限する力を持っている。
  • 訓練や採用へのアクセスが真に平等であって初めて、 差別的報酬が機能的であることが明確に正当化されるはず。

3. 才能を技能に変換するためには、訓練を受ける者が何らかの犠牲を払う訓練期間が必要である。

  • 訓練期間における犠牲
    • 稼ぐ力の放棄(訓練期間の機会費用
      • 平均収入で比べると、エリートが訓練を受けていなかった同年齢の人々の収入を超えて稼ぐまでは、10年かかる。
      • しかし、その後20年間も続く仕事でもなお差別的な報酬が続くのは正当化されない。
    • 訓練期間の費用
      • 一般的には訓練を受ける優秀な若者の親が負担する。
      • 親が特権的な地位にある場合はそこから支払われる。
  • エリート訓練生には、名声やレジャーへのアクセスなど、精神的な報酬もある。
  • 「どのような制度の下でも訓練期間は犠牲的なものでなければならない」という仮定を主張する正当な理論的根拠はないように思われる。
    • 熟練した職業に就く人の訓練には一定のコストがかかるが、そのコストは社会全体が容易に負担することができる。

4. 才能のある人物がこれらの犠牲を払い、訓練を受けるように誘導するためには、彼らの将来のポジションは、社会が提供しなければならない希少で不均衡な報酬への特権的かつ不釣り合いなアクセスという、差別的(differential)な価値を持たせなければならない。

  • 希少で望ましい財やサービスの差別的報酬の配分が、これらのポジションに適切な人材を採用する唯一の方法なのか、それとも最も効率的な方法なのか?
    • 「仕事の内在的な満足度(intrinsic work satisfaction)」や「社会的義務(social duty)」など、別の動機も存在する。
    • このような動機の制度化が不可能であることは証明されていないにも関わらず、暗黙のうちに他の可能性を否定している。

5. これらの希少な報酬や望ましい報酬は、そのポジションに付随する権利や特権からなり、 滋養と快適さ、ユーモアと気晴らし、自尊心と自我の拡大に寄与するものに分類することができる。

6. このような社会の基本的な報酬へのアクセスの差が、様々な階層が獲得する威信と尊敬の差を生むことになるのである。これは、権利や特権とともに、制度化された社会的不平等、すなわち階層化を構成しているといえる。

  • 効果的に機能するためには3つのタイプの報酬をすべて均等に配分しなければならないのか?それとも1つのタイプの報酬が強調されて他の報酬が事実上無視されることがあるのか?
  • 報酬へのアクセスの差が威信と尊敬の差を生むかどうかは非自明。
    • 責任と報酬の合理的なバランスを維持するために重視する報酬の種類が社会によって大きく異なる。
      • e.g. 経済的優位性の差を目立たなくすることが極めて悪趣味とされる社会
    • 規範的秩序に適合する者には、逸脱者とは対照的に、差別的な威信が与えられるということである。

7. したがって、希少財や希望する財の量や、それらが受ける威信や尊敬の量において、異なる階層間の社会的不平等は、いかなる社会においても、積極的に機能するものであり、必然的なものである。

  • ここまでの議論からすれば、不平等の分配にすべきなのは権力と財産だけであると述べてもよいはずなので、威信と尊敬の差異を引き合いに出す必要はない。
  • (権力や財産に関係なく)「一人一人の人間が適切な仕事を良心的にこなす限り、一人一人の人間は他のすべての人間と同じように社会的に価値がある」という考えは、不可能であるとは限らない。

  • 社会階層の逆機能(dysfunction)とは

    • 社会で利用可能な才能の発見を制限する
    • 利用可能な才能の範囲を縮めること(foreshortening)で、社会の生産的資源に制限を設定する
    • エリートに現状追認的なイデオロギーを提供する
    • 好ましい自己イメージを集団全体に不均等に分配する
    • 社会の様々なセグメント間の敵意、疑念、不信感を助長する
    • 社会の中での重要なメンバーであるという感覚を不均等に分配する
    • 社会への忠誠心を不均等に分配する
    • 社会への参加意欲を不均等に分配する

コメント

  • 「社会的閉鎖」「地位の非一貫性」「メリトクラシー」など、そのような語が直接使われているわけではないが、社会階層論のエッセンスが詰まった論文と感じた。特に職業による交渉力の違いは、後続のGruskyらの議論にも通じるものがあるかもしれない。つまり、ある職業が「機能的に重要」と見做されやすいのは、それが政治的・歴史的に獲得されたからであるかもしれない。
  • Davis(1953)による再反論:
    • 機能的重要性について
      • 第一の命題は動機づけについて何も述べていない。
      • 厳密な測定の困難さは、その概念が無意味であることを意味しない。
      • ポジションの違いは、機能的重要性だけでなく、有資格の人材の不足の結果でもあるとはDavisらは既に主張している。
    • 才能に関する知識について
      • 野球のような組織化された選択システムは、効果を発揮するために才能に関する既存の知識を必要としない。
      • ある社会では高い地位が部分的に継承されていると言うことは、同時に威信制度が、有能な人々をその地位に引き込もうと作動していることを否定するものではない。
    • 訓練による犠牲について
      • 訓練による犠牲を上回る報酬を得られるというのは、むしろ理論を補強するものである。
      • 訓練生の精神的報酬が高いとはいえ、勉学は過酷である。
      • 優れた地位にある十分な資格を持った人材を確保することは非常に困難であるため、現代国家は費用の一部を負担しているが、すべてを負担することはできない。
    • 他の動機づけスキームについて
      • もし誰もが自分のやりたいことだけをするように選択したならば、全人口は、数種類の地位にとどまるはず。
        • 生き残った社会は、仕事の喜びを超えて、そうでなければやらないことをやる気にさせ る何らかのシステムを進化させている
      • 社会学者であれば誰でも、社会的に適切な行動を引き出す手段として、報われない利他主義が不十分であることを知っているはずである。
    • 報酬の種類について
      • ある社会が他の社会よりもある種の報酬を強調するかもしれないということで、これらは 不均等に採用されるかもしれないと言っている。これは真実であり、Davisらはそれに反していることは何も言っていない。
    • 逆機能について
      • Davisらは無期限の未来やユートピア的な未来に関心を持っていたのではなく、現在の社会に関心を持っていた。
      • Tuminの「階層化」が地位の継承という意味で使われている。彼の主張する非機能性が真実である限り、犯人は家族であり、地位による報酬の差ではない。
      • 好ましくない自己イメージは、競争的で創造的な活動への強力な刺激となる可能性があるため、これらの機能不全性は明らかではない。
  • Davis-Moore理論(の前提)を実証的に検証しようとする試みがいくつか存在する(Stinchcombe 1963; Broom and Cushing 1977)。
    • Broom and Cushing(1977)…大企業での調査の結果、会社の業績と役員報酬の間には関連が見られなかった。
  • Davis-Moore理論とそれをめぐる論争は、社会学の入門書でしばしば例として挙げられたり、北米の社会学系の学部や大学院で購読される論文となっている一方で、この理論に言及した実証研究はほぼなされないなど、階層研究の表舞台から消えていった。こうした経緯をまとめた論考であるHauhart(2003)のオチが面白いので引用する。

    For those in the profession who critically lambasted the theory (and theorists) as an "apologia for the status quo," the ultimate irony may be the fact that even in death Davis and Moore's theory continues to buttress the class divide? between those who can safely ignore the theory (theprofessorial) and those who cannot (the student). (Hauhart 2003, p.19)

参考文献

  • Broom, L., & Cushing, R. G. (1977). A modest test of an immodest theory: the functional theory of stratification. American Sociological Review, 157-169.
  • Davis, K., & Moore, W. E. (1945). Some principles of stratification. American sociological review, 10(2), 242-249.
  • Davis, K. (1953). Some Principles of Stratification: A Critical Analysis: Reply. American Sociological Review, 18(4), 394-397.
  • Hauhart, R. C. (2003). The Davis–Moore theory of stratification: The life course of a socially constructed classic. The American Sociologist, 34(4), 5-24.
  • Stinchcombe, A. L. (1963). Some empirical consequences of the Davis-Moore theory of stratification. American sociological review, 28(5), 805-808.

Grusky and Sørensen (1998)のメモ

※ゼミ購読文献の担当になっていたので途中までまとめていたのですが、別文献を担当することとなり、もったいないので公開します。

Grusky, D. B., & Sørensen, J. B. (1998). Can class analysis be salvaged?. American journal of Sociology, 103(5), 1187-1234.

  • 伝統的な階級分析に対する批判を行い、階級分析を再び方向づけるような形で再構築するのが本稿の狙い
  • 階級分析の批判者が採用するアプローチ
    • 修正主義(revisionisim)
      • ポスト産業社会への移行に伴い、階級や職業は、学校や職場といったアリーナに道を譲っている
    • 脱構築主義者(deconstructionalist)
      • 文化の重要性を強調する立場
      • 労働運動から、ライフスタイルやアイデンティティに基づいた新たな社会運動
    • 階級モデルの重要性を再確認しつつ、改修や再構築を行ってもなお、その効力は弱くなっているとする立場
  • 階級分析の分析的な軸
    • 実質 vs 名目 / 連続的 vs. 離散 / 集約的 vs. 非集約的
    • 著者らは名目・離散・非集約的の立場を取る
  • 分業
    • 技術的分業概念の誤解:分業における機能的なグループ化は名目的なものであり、したがって、社会的な行動や識別の意味のある基盤を構成する社会的なグループ化になる可能性は低い
    • 現代の傾向は、一方では職業的なグループ化と他方では「タスク・ニッチ」の間の動的なマッチング・プロセスの結果として分業を扱うこと
      • ある職業は、法的・政治的・経済的な闘争の結果である
  • アイデンティティ…自己認識
    • マルクスは個人が集合的な階級を認識し、集合的な階級と同一視するようになると想定していたのに対し、デュルケムは集合的な職業に関しても同様のことを想定していた
    • 専門的な職業がアイデンティティを形成するという研究もあるが、性的嗜好など、他にもアイデンティティの源が存在する
  • アウェアネス…他者認識
    • 労働者の思い描く階層モデルは研究者のそれとは異なる。ばらつきがある
      • 回答者の 35~45%が労働者階級を不釣り合いに大きいと表現し、別の 55%が人口がまばらな両極端の間にある膨らんだ中産階級を表現し、残りの 55%が上部中産階級の拡大した上部重厚な社会を想像していた
      • 職業分類は先進的な産業主義の制度の中に埋め込まれているのに対し、階級の集合的な概念は現代の社会システムからは比較的周辺的な学術的構成物である
  • 社会的閉鎖
    • 私有財産:「生産手段とその果実への 一般的なアクセスを妨げる」
    • 信任主義:「分業における 重要な地位への参入を制御し、監視する」
    • 閉鎖理論の中での不幸な傾向は、このようにして、 工芸労働組合を完全に無視するか、あるいは弱くて取るに足らない 閉鎖の源泉として扱うことであった
    • ユニオンショップは効果的な排除手段にもなりうるし、雇用や解雇に関する統制を職業代表者や現職者に委ねる様々な形態の専門家による閉鎖も可能である
    • 排除的な目的を明らかに実現できていない職業もあれば(例:看護師)、そのような目的を追求していない、あるいは明確にしていない職業もある
  • 単位職業レベルでの集団行動の 3 つの主要なタイプは:
    • 職業的地位へのアクセスを制限するために設計された下方に向けられた閉鎖戦略
    • 分業における機能的なニッチをめぐる職業団体間の横方向の競争闘争
    • 国家や使用者からの職業固有の利益(例えば、独占保護)の確保を目的とした上方に向けられた集団行動
  • ライフスタイルと気質
    • 分析的な関心が個人レベルに向かって高まっている。したがって、近代的な階級分析の知的根拠は、階級のメンバーシップがあらゆる種類の個人レベルの結果(例えば、態度、投票行動、消費行動)を条件としているという単純な実証的観察に、ますます依存するようになっている
    • 近代的な閉鎖が主に詳細な職業レベルで確保されており、その結果として社会的相互作用が制限され、それに対応して離散的な職業的サブカルチャーが生成されている
  • 構造的な説明
    • ネオマルクス主義:搾取の根本的な軸を探す
    • 現代経済における不平等の多くは、現在では労働市場で発生しているが、搾取のオーソドックスな概念は、賃金所得者から資本家への余剰価値の移転に排他的に焦点を当てることで、このような不平等を無視している
  • 構造化のトレンド
    • 社会-技術的な変化
      • ポスト・フォード主義者は、初期の工業主義が実際には多くの職人を促進したことを示唆しているが、このプロセスは、「フォード主義」の工場が小規模生産、柔軟な専門化、および若返った職人的部門に徐々に取って代わられ、マルクスが消滅すると約束した手作業のそれらの区別を再び導入するのに役立つものはすべて、それ自体を逆転させていると主張されている
      • もし、柔軟な特殊化が職人的生産に新たな生命を吹き込むというポスト・フォード主義の中核的な主張を受け入れるならば(例えば、Piore and Sabel 1984)、適切な意味合いは、生産に基づくすべての連帯性が枯れていくということではなく、むしろそのような連帯性がますます局所化していくということである
    • 組織的な変化
      • 垂直的な管理方法は、ポスト工業化主義の進展に伴って、職業的に定義された労働を侵食し続けるのか?
      • 現代の組織が従来のスキルベースの区別を打ち破るチームワーク、クロストレーニング、および多動性の仕事にますます依存している
    • 組合の変化
      • 「組合運動の包括性」(Visser 1988, p.167)の明らかな弱体化にもかかわらず、純粋に局所的な組合・組合が労働者を支配する力を失っていないことを示唆する多くの証拠がある
    • 結論
      • 本稿では職業集団が国家と個人の間に介在し、階級形成の脅威になるというデュルケム的な階級論を提示した
      • 重要な問い
        • 階級の職業集団への分解により、クラスモデルの説明力が大幅に向上するのか?
        • ポストモダニストが主張するように社会階級は分解されているのか?
        • 社会的移動の根本的な構造は集約的分類によって誤代表されているのか?
        • 背景効果は従来の階級や社会経済的尺度で十分にコントロールされているか?
        • 生産の現場では、態度、生活様式、および状況はどのように形成されているのか?
      • この代替的アプローチでは、職業が社会的に構築されたものであることを最初から認め、それに応じて階級区分を定義することで、新マルクス主義的な構造と行動の離婚によって生じる問題を回避することができる

ggplot2で多重クロス表を作る

  • 最近は大学院の研究でひたすら3重クロス表の分析を行っています。
  • Rでは xtable パッケージの xtable() を使うと2重クロス表をTeX形式で出力してくれるのですが、3重以上の多重クロス表には対応していません。
    • gridExtra::grid.table() を使う方法もあるかと思いますが、余白の扱いや多重の場合が少し面倒な印象があります。
  • そこで今回は、ggplot2を使った多重クロス表の出力方法を紹介します

セッション情報

  • 毎度のことながらrstudio cloud上で動かしています。
> sessionInfo()
R version 3.5.3 (2019-03-11)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.6 LTS

Matrix products: default
BLAS: /usr/lib/atlas-base/atlas/libblas.so.3.0
LAPACK: /usr/lib/atlas-base/atlas/liblapack.so.3.0

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8        LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
 [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C           LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

下準備

{MASS} パッケージ内の Cars93 データを用います。

library(tidyverse)
data <- MASS::Cars93

まずは普通に出力

  • 車種(Type)、駆動系(DriveTrain)、生産国(Origin)の3重クロス表を作成します。
crosstab <- data %>% select(Type,DriveTrain,Origin) %>% table
> crosstab
, , Origin = USA

         DriveTrain
Type      4WD Front Rear
  Compact   0     7    0
  Large     0     7    4
  Midsize   0     9    1
  Small     0     7    0
  Sporty    2     2    4
  Van       3     2    0

, , Origin = non-USA

         DriveTrain
Type      4WD Front Rear
  Compact   1     6    2
  Large     0     0    0
  Midsize   0     8    4
  Small     2    12    0
  Sporty    0     5    1
  Van       2     2    0

geom_tileを使ってplotする

  • 何はともあれtidyに。
tidy_crosstab <- as.data.frame.table(crosstab)
> tidy_crosstab
      Type DriveTrain  Origin Freq
1  Compact        4WD     USA    0
2    Large        4WD     USA    0
3  Midsize        4WD     USA    0
4    Small        4WD     USA    0
5   Sporty        4WD     USA    2
6      Van        4WD     USA    3
7  Compact      Front     USA    7
8    Large      Front     USA    7
9  Midsize      Front     USA    9
10   Small      Front     USA    7
11  Sporty      Front     USA    2
12     Van      Front     USA    2
13 Compact       Rear     USA    0
14   Large       Rear     USA    4
15 Midsize       Rear     USA    1
16   Small       Rear     USA    0
17  Sporty       Rear     USA    4
18     Van       Rear     USA    0
19 Compact        4WD non-USA    1
20   Large        4WD non-USA    0
21 Midsize        4WD non-USA    0
22   Small        4WD non-USA    2
23  Sporty        4WD non-USA    0
24     Van        4WD non-USA    2
25 Compact      Front non-USA    6
26   Large      Front non-USA    0
27 Midsize      Front non-USA    8
28   Small      Front non-USA   12
29  Sporty      Front non-USA    5
30     Van      Front non-USA    2
31 Compact       Rear non-USA    2
32   Large       Rear non-USA    0
33 Midsize       Rear non-USA    4
34   Small       Rear non-USA    0
35  Sporty       Rear non-USA    1
36     Van       Rear non-USA    0
  • ggplotにつっこむ。
g <- ggplot(data = tidy_crosstab, aes(x = Type, y = DriveTrain, label = Freq))
g <- g + geom_tile(fill = "white",col = "black")
g <- g + geom_text()
g <- g + facet_wrap(~Origin, nrow = 1)
  • 出力されるのはこんな感じの画像になります。

f:id:meana0:20200310220153p:plain

4重クロス表

  • AirBagという変数を増やした4重クロス表を出力します
  • 今度は、facet_grid() を使います。
crosstab2 <- data %>% select(Type,DriveTrain,AirBags,Origin) %>% table
tidy_crosstab2 <- as.data.frame.table(crosstab2)
g <- ggplot(data = tidy_crosstab2, aes(x = Type, y = DriveTrain, label = Freq))
g <- g + geom_tile(fill = "white",col = "black")
g <- g + geom_text()
g <- g + facet_grid(Origin ~ AirBags)

f:id:meana0:20200310222149p:plain

{gnm}を使ったクロス表の分析

【2021/03/12更新:p値をカイ2乗値から計算していましたがdeviance由来に修正しました】

  • 最近は対数線形・対数乗法モデルの復習をしています。
  • 色々と読み返してはいるのですが、以下の本は簡潔にまとまっており、非常に勉強になりました。
  • オッズ比から始まって、RC(M)-L modelまで取り扱っています。

  • 今回は備忘録も兼ねて、同書のExample2.2をRの{gnm}パッケージを使って一部再現しようと思います。
    • Rでの対数線形・対数乗法モデルの実装方法に関しては、あまりまとまった日本語の資料がないようでした。
    • モデル自体の解説は日本語でもすぐに資料が見つかると思います。

github.com

データの用意

  • 同書に記載ある通り、学歴(EDUC)と現職(OCC)のクロス表 ex.2.2.txt を用意します。
  • 元ネタはGSS(1985-1990 cumulative, 女性のみ)のようです。
,上層ノンマニュアル,下層ノンマニュアル,上層マニュアル,下層マニュアル,農業
大卒以上,518,95,6,35,5
短大,81,67,4,49,2
高校,452,1003,67,630,5
高校未満,71,157,37,562,12

実行環境

> sessionInfo()
R version 3.4.4 (2018-03-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.2 LTS

Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8        LC_COLLATE=C.UTF-8    
 [5] LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8    LC_PAPER=C.UTF-8       LC_NAME=C             
 [9] LC_ADDRESS=C           LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] purrr_0.3.3 dplyr_0.8.3 gnm_1.1-0  

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.1       lattice_0.20-35  crayon_1.3.4     relimp_1.0-5     assertthat_0.2.1 MASS_7.3-51.5   
 [7] grid_3.4.4       R6_2.4.0         magrittr_1.5     pillar_1.4.2     rlang_0.4.2      qvcalc_1.0.1    
[13] rstudioapi_0.10  Matrix_1.2-18    tools_3.4.4      glue_1.3.1       compiler_3.4.4   pkgconfig_2.0.2 
[19] tidyselect_0.2.5 nnet_7.3-12      tibble_2.1.3    

ライブラリ読み込み

library(gnm)
library(dplyr)
library(purrr)

前処理

  • 何はともあれ、行ラベル・列ラベル・頻度からなるtidyなデータフレームにします。
tab <- read.table("ex.2.2.txt",header = TRUE,sep = ",",row.names = 1)
mat <- as.matrix(tab)
df <- as.data.frame.table(mat)
colnames(df) <- c("EDUC","OCC","Freq")
> df
       EDUC                OCC Freq
1  大卒以上 上層ノンマニュアル  518
2      短大 上層ノンマニュアル   81
3      高校 上層ノンマニュアル  452
4  高校未満 上層ノンマニュアル   71
5  大卒以上 下層ノンマニュアル   95
6      短大 下層ノンマニュアル   67
7      高校 下層ノンマニュアル 1003
8  高校未満 下層ノンマニュアル  157
9  大卒以上     上層マニュアル    6
10     短大     上層マニュアル    4
11     高校     上層マニュアル   67
12 高校未満     上層マニュアル   37
13 大卒以上     下層マニュアル   35
14     短大     下層マニュアル   49
15     高校     下層マニュアル  630
16 高校未満     下層マニュアル  562
17 大卒以上               農業    5
18     短大               農業    2
19     高校               農業    5
20 高校未満               農業   12

分析

  • まずはクロス表全体としてオッズ比が1になる independent model を作ります。
  • 一般化非線形モデルを推定するためのパッケージ{gnm}を使います。
> gnm(formula = Freq ~ EDUC + OCC, data = df, family = poisson)

Call:
gnm(formula = Freq ~ EDUC + OCC, family = poisson, data = df)

Coefficients:
          (Intercept)               EDUC短大               EDUC高校           EDUC高校未満  
               5.2557                -1.1775                 1.1858                 0.2415  
OCC下層ノンマニュアル      OCC上層マニュアル      OCC下層マニュアル                OCC農業  
               0.1640                -2.2867                 0.1286                -3.8448  

Deviance:            1373.176 
Pearson chi-squared: 1455.658 
Residual df:         12 
  • ここから階層的にモデルを作っていきます。
  • RモデルやCモデルを作るためには、推定の問題上、パラメータを標準化し、足して0になるように制約をかける必要があります。
Row <- scale(as.numeric(row(mat)), scale = TRUE)
Col <- scale(as.numeric(col(mat)), scale = TRUE)
  • 本来であればR+C+RCモデルなども記載があるのですが、パラメータ制約がややこしいので省略しています。
  • あとで map() するため、結果をlistに放り込んでいきます。
set.seed(1024)
gnm_list <- list()
gnm_list$O <- gnm(formula = Freq ~ EDUC + OCC, data = df, family = poisson)
gnm_list$U <- update(gnm_list$O, ~ . + Row:Col)
gnm_list$R <- update(gnm_list$O, ~ . + EDUC:Col)
gnm_list$C <- update(gnm_list$O, ~ . + OCC:Row)
gnm_list$RpC <- update(gnm_list$O, ~ . + EDUC:Col + OCC:Row) #R+Cモデル
gnm_list$RC <- update(gnm_list$O, ~ . + Mult(EDUC,OCC))
gnm_list$RC2 <- update(gnm_list$RC, ~ . + Mult(EDUC,OCC,inst = 2))
  • さて、無事に各モデルが推定できたはずです。

モデルの適合度

  • 次は各モデルの適合度を見ていきます。どのモデルが最もクロス表をよく説明するでしょうか。
  • 自由度df、逸脱度G2(-2log尤度)、p値、BICの4つを出力します。
fit_df <- function(gnm_object){
  df <- gnm_object$df.residual
  g_sq <- gnm_object$deviance
  p_value <- 1 - pchisq(q = gnm_object$deviance ,df = gnm_object$df.residual)
  bic <- g_sq - gnm_object$df.residual * log(sum(gnm_object$data$Freq))
  fit_df <- data.frame(df,g_sq,p_value,bic)
  return(fit_df)
}

gof <- bind_rows(map(gnm_list,fit_df),.id = "model")
  • 結果を見てみます。
> gof
  model df         g_sq  p_value        bic
1     O 12 1373.1757657 0.0000000 1274.08092
2     U 11  244.0177150 0.0000000  153.18077
3     R  9  205.9735836 0.0000000  131.65245
4     C  8  155.3722685 0.0000000   89.30903
5   RpC  6   91.6077617 0.0000000   42.06034
6    RC  6  125.0597486 0.0000000   75.51232
7   RC2  2    0.6001022 0.7407804  -15.91571
  • 最後のRC(2)モデルが最もBICが低く、かつp値も大きいため、このモデルが選択されます。

    • p値が大きいというのは、Χ2値が小さい、つまり、RC2モデルによって求められる各セルの期待度数が、元データからそれほど乖離していないことを示しています。
    • 本来は、自由度をいくつ使ってG2が改善したかなども併せて見ていく必要がありますが…。
  • RC(2)モデルのパラメータはこのような感じになります。

> gnm_list$RC2

Call:
gnm(formula = Freq ~ EDUC + OCC + Mult(EDUC, OCC) + Mult(EDUC, 
    OCC, inst = 2), family = poisson, data = df)

Coefficients:
                                  (Intercept)                                       EDUC短大  
                                     5.066410                                      -0.916769  
                                     EDUC高校                                   EDUC高校未満  
                                     1.067655                                       0.217877  
                        OCC下層ノンマニュアル                              OCC上層マニュアル  
                                     0.353842                                      -2.143860  
                            OCC下層マニュアル                                        OCC農業  
                                     0.129995                                      -3.973502  
                    Mult(., OCC).EDUC大卒以上                          Mult(., OCC).EDUC短大  
                                    -5.581051                                      -1.462538  
                        Mult(., OCC).EDUC高校                      Mult(., OCC).EDUC高校未満  
                                     0.975465                                       1.973569  
          Mult(EDUC, .).OCC上層ノンマニュアル            Mult(EDUC, .).OCC下層ノンマニュアル  
                                    -0.249405                                       0.099685  
              Mult(EDUC, .).OCC上層マニュアル                Mult(EDUC, .).OCC下層マニュアル  
                                     0.222067                                       0.314239  
                        Mult(EDUC, .).OCC農業            Mult(., OCC, inst = 2).EDUC大卒以上  
                                    -0.013403                                       1.240632  
              Mult(., OCC, inst = 2).EDUC短大                Mult(., OCC, inst = 2).EDUC高校  
                                     0.683454                                      -1.323081  
          Mult(., OCC, inst = 2).EDUC高校未満  Mult(EDUC, ., inst = 2).OCC上層ノンマニュアル  
                                     3.154406                                      -0.168216  
Mult(EDUC, ., inst = 2).OCC下層ノンマニュアル      Mult(EDUC, ., inst = 2).OCC上層マニュアル  
                                    -0.246388                                       0.007613  
    Mult(EDUC, ., inst = 2).OCC下層マニュアル                Mult(EDUC, ., inst = 2).OCC農業  
                                     0.094214                                       0.382994  

Deviance:            0.6001022 
Pearson chi-squared: 0.5746549 
Residual df:         2 
  • RC effectの1次元目は学歴・職業階層の一次元的な”序列”を表していそうです。
    • つまり、高い(低い)学歴が高い(低い)職業的地位と結びついている
  • 一方で2次元目は解釈が難しく、筆者によればこれはメリトクラシーでは説明できない、労働市場の参入障壁を表しているといいます。
    • RC(M)モデルの Mを増やせば説明力は上がりますが、その解釈は分析者の腕の見せどころですね…。

xtableのエスケープを抑制する

xtableを使うとmatrixやdataframeをTeX形式の表に変換してくれて便利です。 しかし、表の中に数式などが含まれている場合、xtableの出力結果の中で _{ の前にエスケープ文字列 \ がつく場合があります。 当然、出力結果を貼り付けてそのままコンパイルすると、適切に数式が表示されません。

> library(tidyverse)
> library(xtable)
> 
> d <- tibble(Variable = c("$\\hat{X}$"),
+             Value = "0.1")
> xtable(d)
% latex table generated in R 3.5.3 by xtable 1.8-4 package
% Tue Jan 28 14:28:26 2020
\begin{table}[ht]
\centering
\begin{tabular}{rll}
  \hline
 & Variable & Value \\ 
  \hline
1 & \$$\backslash$hat\{X\}\$ & 0.1 \\ 
   \hline
\end{tabular}
\end{table}

xtableオブジェクトをprint関数に渡して以下のようにオプションを指定すると、エスケープしません。これは複数指定できます。

#列ラベルのエスケープを抑制したい場合
xtable(d) %>% print(sanitize.colnames.function = identity)
#行ラベルのエスケープを抑制したい場合
xtable(d) %>% print(sanitize.rownames.function = identity)
#各要素のエスケープを抑制したい場合
xtable(d) %>% print(sanitize.text.function = identity)

上の例で実際にやってみると、確かにエスケープされなくなります。

xtable(d) %>% print(sanitize.text.function = identity)
% latex table generated in R 3.5.3 by xtable 1.8-4 package
% Tue Jan 28 14:28:59 2020
\begin{table}[ht]
\centering
\begin{tabular}{rll}
  \hline
 & Variable & Value \\ 
  \hline
1 & $\hat{X}$ & 0.1 \\ 
   \hline
\end{tabular}
\end{table}

参考:

print.xtable function | R Documentation