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 } ] }, ...
Manufacturer
と Type
の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年間の休学を経ての復学となりました。就職までの経緯については、過去に公開した以下のエントリで紹介しています。
就職してから、それなりに充実した生活を送れていたのですが、ずっと「論文を書いていない」「学位を取っていない」ことの後ろめたさが残っていました。こうした心的負荷は次第に大きくなっていき、もはや無視できるレベルではないと感じたため、20代の残り時間で論文投稿や博士論文執筆に取り組むことを決意しました。
入社から1年半ほどが経過してから、人事評価など、折りを見て上司に復学する可能性を伝えていました。復学前から大学院のゼミには仕事終わりに週1回出席し、途中で挫折していた修士論文の投稿論文化を進めたりと、ゆっくりと大学院生活に向けたリハビリを行いました。私が通っている大学院は社会人用の夜間コースではなく、課程博士のコースなのですが、ゼミがたまたま6限に開講されていたため、定時上がりをすれば参加することができました。
いきなり復学するのではなく、このようなバッファの期間を作ったことで、会社側と調整する時間を確保しつつ、「自分が働きながら本当に研究活動を続けていけるかどうか」を正確に判断することができました。最終的には、人事と交渉しながら、仕事を週1日休みの時短勤務にしてもらい、正式に復学しました(勤務先の企業には感謝してしきれません)。
研究・博士論文について
ちなみに、大学院博士課程では社会学を専攻しており、主に「趣味やオンラインメディアと社会ネットワークにおける同類結合の関係性」について研究しています。博士論文では、簡単に言うと「趣味やオンラインメディアは同類結合を緩和する可能性がある」という主張をする予定です。審査に通った暁には、公開すること機会があるかもしれません。
他分野では博士論文提出の要件として投稿論文2~3本の掲載を課している大学院も多いようですが、社会学の業界でそのような風潮は稀薄で、ほとんどの場合、投稿論文を集めたベストアルバムというよりも、重厚長大な大河ドラマのような博士論文が要求されます。
したがって、博士号取得のために論文投稿は必須のステップではありません。しかしながら、長きにわたる博士論文全体のマイルストーン的な意味合いや、各章で行っている先行研究の整理や分析を洗練させるために査読という外部システムが有用であることから、各章の内容はできるだけ論文化しようとしています。ちなみに、社会学における博士論文の書き方については、以下のnoteが非常に参考になります。
復学後にやったこと
2020年に研究関連で行ったことを以下にまとめました。
1月 | 修士論文の内容を再構成して投稿 |
2月 | 博士論文第3章にあたる論文を書く |
3月 | 査読結果(ラウンド1)が帰ってくる |
4月 (時短勤務に変更) | 査読対応 → 再投稿 |
5月 | 博士論文第3章にあたる論文を書く |
6月 | 査読結果(ラウンド2)が帰ってくる |
7月 | 査読対応 → 再投稿 |
8月 | 博士論文全体の構成を検討する作業 |
9月 | 査読結果(ラウンド3)が帰ってくる → 掲載決定 |
10月 | 博士論文第3章にあたる論文を書く |
11月 | 博士論文中間発表 |
12月 | (博士論文第3章にあたる論文を投稿予定) |
年始は3本の論文投稿(+研究ノート1本)を目標としていましたが、現実はなかなか厳しく、1本投稿(出版)と頑張ればもう1本投稿できるかできないか、という結果となってしまいました。こうして振り返ってみると、査読対応にかなりの時間が奪われていることがわかりますね…。論文投稿から出版までの過程については、後述しようかと思います。ちなみに、以下のページから拙著を読むことができますので、関心のある方はチェックしてみていただけると幸いです。
前向きに捉えると査読対応の合間に博士論文全体の構成を固めることができたので、今後1年間はその構成を具体化できるかの勝負になってくるかと思います。
研究を続け(させ)るためにやったこと
ここからは、この1年間、働きながら大学院での研究活動を続けるため、あるいは、自分に研究活動を続けさせるために何が必要だと思ったか、そのためにどんなサービスを採用したか、どんな生活習慣を取り入れたかについて書きます。結局のところ、自分の場合は「やる気を(再)燃焼させる」「タスクを細分化する」「生活リズムを崩さない」「好きなことを捨てない」という4点に収斂するかと思います。
やる気を(再)燃焼させる
研究のモチベーション管理について、実を言うと私の場合は「研究が楽しくて仕方がない!」というモードははるか昔に通り過ぎてしまっています。「この研究テーマは自分以外には取り組んでいないものなので、完遂する必要がある」という使命感を持っていることは事実ですが、同時に、自分の中で燃え殻のようなやる気が消えないよう、必死に空気を送り込み、火種を絶やさないようにしているのが現状です。
私の場合は、「やる気があるから作業する」ということはほとんどなく、「作業するからやる気が出てくる」というケースがほとんどです。一度作業を始めると、色々とやるべきことが見えてきて、結局長時間作業を継続することができます。したがって、半強制的にまとまった時間を作業する習慣を作ることが重要になります。
そこで、ポモドーロ・テクニック(以下ポモと表記)を使っています。簡単に言うと、25分集中+5分休憩のサイクルを繰り返すことを指します。1ポモでエンジンが入ることもあれば、5ポモやってからやっとやる気が出てくる、ということもあります 。研究室の後輩がポモドーロ・テクニックについての秀逸な解説記事を書いているので、一読をおすすめします。
ポモをするためのタイマーアプリは様々あるのですが、私はForestというアプリをスマートフォンとPCに入れています。Forestはポモのためのアプリではなく、スマホ依存を解消するためのアプリですが、優秀なポモタイマーとして使うこともできます。Forestの機能はいたってシンプルです。まず時間を決めます。ボタンを押すと木が育ち、決められた時間の間にTwitterを開いたりすると、木が枯れます(悲しい)。たったこれだけですが、n日連続で木を植え続けると称号が獲得できたり、植えられる木の種類が増えていき、作業する習慣が根付いていきます(木だけに)。
Forestは、インセンティブの設計が絶妙です。単なるタイマーだと蓄積するインセンティブがありませんが、以下の画像のように作業した分だけ森が広がっていく様を確認すると、ホクホクした気分になります。作業をやめた時のペナルティが「木が枯れる」なのも良い塩梅だと思います。仮に、途中でやめると「キャラクターが死ぬ」だとあまりにかわいそうな気持ちになってしまいます。また、Chrome拡張を入れるとTweetDeckやFacebookなどのページが強制的に黒くマスキングされて見えないようになる(アーキテクチャによる行為の制限!)のも高評価ポイントです。
下の画像は、緊急事態宣言化で毎日在宅勤務していた時の植樹記録です。通勤時間がないので、その分研究に時間が使えています。働きつつここまで作業できているのは、少しだけ自分を褒めてあげてもいいかなと思っています。このように、研究に費やした時間を可視化することは、「自分はやれている」という自己効力感を得るメリットがあります。
タスクを細分化する
働きながら論文を書くとなると、12時間など大きな連続領域を確保することが難しくなるため、小さなまとまった時間を確実に積み上げていくことが重要になります。そこで、タスクのほうも小さくするのがベターです。
仕事と研究どちらでもタスクの管理はNotionで行っています。下の画像は、査読コメントから、約100個の作業内容に落とし込んだテーブルと、現在の研究活動のタスクボードです。査読コメントのテーブル場合、一つ一つの作業をタイプ別に分類しています。例えば表現に関するものであればExpressionというタグを、分析に関するものであればAnalysisというタグをつけます。タグは同時に作業の難易度も表しているので、「明日は残業するかもしれないから、Expressionの修正だけ行おう」というようなタスクの優先度をつけることもできます。タスクボードは、今書いている論文などで必要な作業の進捗をTodo, Doing, Doneに分けて管理するものです。これは自分で作ったものではなく、Notionの既存のテンプレートを利用しています。タスク管理が主な目的ですが、Doneの列にタスクが積み上がっていくと、達成感と同時に、Forestアプリの森と同じように、「やれている」という自己効力感を得ることができます。
最近は「あえてやり残しを作る」のも重要だと感じています。つまり、常にTodoの部分にタスクがある状態を作ることです。自分の癖として、「何をやらなければならないか」が明瞭でない状態に、最も机に向かう気力がないという経験則があります。論文を書いていると、作業をしているうちに新たな作業の必要性が明らかになってくる、ということがよくあります。そうしたタスクの連鎖をコントロールするためにも、常に向き合うべきタスクがある、という状態に置くようにしています。
生活リズムを崩さない
研究生活の基盤を形づくるのが生活リズムです。私の体質的に、油断すると睡眠リズムは一気に崩れてしまうので、これは本当に大事です。具体的には下記のエントリで書いていることを引き続き実践しています。現代文明の力を駆使することと、休日に寝すぎないのがコツです。ちなみに先日、Nature RemoのAWS障害で会社に遅刻しかけました。
好きなことを捨てない
また自分語りになってしまいますが、私には、抱えきれないほど多くの趣味があります。早朝に起きてモノレールに乗って野鳥観察をしたと思えば、部屋にこもってスプラトゥーン2をしたり、夜は千駄木で延々と野良猫を探したり…など、きわめて複層的で、焦点の定まらない生活を送っています。
学生の頃はけん玉、フリースタイルラップ(の真似事)、料理、Webスクレイピング、大学の施設で無料で映画鑑賞、自転車で23区内のサブウェイを全部回ってどこのポテトが一番美味しいかを検証する…などの安価に楽しめるアクティビティに興じていましたが、定収のある生活を始めてからは、ますます好きな趣味が増えてしまいました。自分が1ヶ月後どんなことに耽溺するか、まったく予想できません。
「いかに研究以外のことを考えるか」で悩む人も多いようですが、自分の場合は、「絡まりきった趣味生活の中に、いかにして研究活動をねじ込むか」が主な課題になります。そこでForestの活用やタスクの細分化などが有効となるわけです。
とは言いつつも、復学する上で、多数の趣味があることは足枷になるどころか、むしろ背中を押してくれる要因になったと感じています。どういうことかというと、「これだけ好きなものがあるのだから、いつでも戻ってこれる」という謎の自信がつくためです。
ライムスターの宇多丸さんは、先日話題になった記事でこのように語っています。
自分が好きなものをわかってる人は勝ち組ですよ、それだけで。だって、それで確実に楽しくなるんだもん。もちろん、人生いろんな局面が来るから、そこが灰色に見えだすときもある。そんなときに、いろんなチャンネルを持っているといいんですよね。『最近、オレなんか音楽にはピンとこねえな』ってときも、今はゲームなんです、今は映画なんです、今は酒なんですで別にいいんです。美味しい飯とかでもいいじゃんって
宇多丸さんの発言とは少し離れてしまうかもしれませんが、好きなものに囲まれていると、自分の場合は「そしたら、ちょっとつらいこともやってみようか」という気分になります。悪く言えば「現実逃避」ですが、宿命的につらい時、逃避できる何かの存在は、時として現実と向き合うための勇気を与えてくれます。
さいごに
「社会人大学院生」「二足のわらじを履く」と聞くと、ストイックな人物像や過酷な生活を連想します。「あらゆる余暇時間を削って研究に没頭する」のが理想だとは思いますが、人生は長く、来年学位を取らなければ死ぬわけでもないので、最近では適度に肩の力を抜きつつやっていけばいいと思うようになりました。振り返ってみると、習慣化して、コツコツ積み上げていくことが大事という極めてシンプルな結論に辿り着きます。小学生の時に気付きたかった事実です。
来年もどうぞよろしくお願いいたします。
社会的不平等は社会的機能ではない――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)。その主張内容は、以下の命題に集約可能。
- いかなる社会においても、ある特定のポジションは他のポジションよりも機能的に重要であり、そのパフォーマンスのために特別な技能(skills)を必要とする。
- いかなる社会においても、これらのポジションにふさわしい技能に訓練することができる才能(talents)を持っているのは、限られた数の個人だけである。
- 才能を技能に変換するためには、訓練を受ける者が何らかの犠牲を払う訓練期間が必要である。
- 才能のある人物がこれらの犠牲を払い、訓練を受けるように誘導するためには、彼らの将来のポジションは、社会が提供しなければならない希少で不均衡な報酬への特権的かつ不釣り合いなアクセスという、差別的(differential)な価値を持たせなければならない。
- これらの希少な報酬や望ましい報酬は、そのポジションに付随する権利や特権からなり、 滋養と快適さ、ユーモアと気晴らし、自尊心と自我の拡大に寄与するものに分類することができる。
- このような社会の基本的な報酬へのアクセスの差が、様々な階層(strata)が獲得する威信と尊敬の差を生むことになるのである。これは、権利や特権とともに、制度化された社会的不平等、すなわち階層化(stratification)を構成しているといえる。
- したがって、希少財や希望する財の量や、それらが受ける威信や尊敬の量において、異なる階層間の社会的不平等は、いかなる社会においても、積極的に機能するものであり、必然的なものである。
以下、それぞれの命題について批判的な検討を行っていく。
1. いかなる社会においても、ある特定のポジションは他の地位よりも機能的に重要であり、そのパフォーマンスのために特別な技能(skills)を必要とする。
- 「機能的に重要(functionally important)」という語の不明瞭さ
- 機能性の重要度が暗黙の価値選好によって行われている可能性
- どの職業であれ、経営者はモチベーションの問題には短期的に向きわなければならない。
- 一部の、交渉力(bargaining power)が高い職種もあるが、それは結果として得られたものにすぎない。
- 誘引や報酬は、数ある動機付けシステムの中の多くのバリエーションの一つにすぎない。
2. いかなる社会においても、これらのポジションにふさわしい技能に訓練することができる才能(talents)を持っているのは、限られた数の個人だけである。
- 人口の中に存在する才能の存在と、その知識に対する疑問
- 社会が厳格に階層化されればされるほど、その社会がメンバーの才能についての新しい事実を発見する機会は少なくなる。
- e.g. 訓練へのアクセスが親の富に依存し、富の分配が異なる社会では、人口の大部分が自分の才能を発見する機会すら奪われてしまう可能性
- 社会が厳格に階層化されればされるほど、その社会がメンバーの才能についての新しい事実を発見する機会は少なくなる。
- ある世代における報酬の不平等な分配は、後続の世代におけるモチベーションの不平等な分配をもたらす傾向がある。
- エリートは訓練や採用を制限する力を持っている。
- 訓練や採用へのアクセスが真に平等であって初めて、 差別的報酬が機能的であることが明確に正当化されるはず。
3. 才能を技能に変換するためには、訓練を受ける者が何らかの犠牲を払う訓練期間が必要である。
- 訓練期間における犠牲
- 稼ぐ力の放棄(訓練期間の機会費用)
- 平均収入で比べると、エリートが訓練を受けていなかった同年齢の人々の収入を超えて稼ぐまでは、10年かかる。
- しかし、その後20年間も続く仕事でもなお差別的な報酬が続くのは正当化されない。
- 訓練期間の費用
- 一般的には訓練を受ける優秀な若者の親が負担する。
- 親が特権的な地位にある場合はそこから支払われる。
- 稼ぐ力の放棄(訓練期間の機会費用)
- エリート訓練生には、名声やレジャーへのアクセスなど、精神的な報酬もある。
- 「どのような制度の下でも訓練期間は犠牲的なものでなければならない」という仮定を主張する正当な理論的根拠はないように思われる。
- 熟練した職業に就く人の訓練には一定のコストがかかるが、そのコストは社会全体が容易に負担することができる。
4. 才能のある人物がこれらの犠牲を払い、訓練を受けるように誘導するためには、彼らの将来のポジションは、社会が提供しなければならない希少で不均衡な報酬への特権的かつ不釣り合いなアクセスという、差別的(differential)な価値を持たせなければならない。
- 希少で望ましい財やサービスの差別的報酬の配分が、これらのポジションに適切な人材を採用する唯一の方法なのか、それとも最も効率的な方法なのか?
- 「仕事の内在的な満足度(intrinsic work satisfaction)」や「社会的義務(social duty)」など、別の動機も存在する。
- このような動機の制度化が不可能であることは証明されていないにも関わらず、暗黙のうちに他の可能性を否定している。
5. これらの希少な報酬や望ましい報酬は、そのポジションに付随する権利や特権からなり、 滋養と快適さ、ユーモアと気晴らし、自尊心と自我の拡大に寄与するものに分類することができる。
6. このような社会の基本的な報酬へのアクセスの差が、様々な階層が獲得する威信と尊敬の差を生むことになるのである。これは、権利や特権とともに、制度化された社会的不平等、すなわち階層化を構成しているといえる。
- 効果的に機能するためには3つのタイプの報酬をすべて均等に配分しなければならないのか?それとも1つのタイプの報酬が強調されて他の報酬が事実上無視されることがあるのか?
- 報酬へのアクセスの差が威信と尊敬の差を生むかどうかは非自明。
- 責任と報酬の合理的なバランスを維持するために重視する報酬の種類が社会によって大きく異なる。
- e.g. 経済的優位性の差を目立たなくすることが極めて悪趣味とされる社会
- 規範的秩序に適合する者には、逸脱者とは対照的に、差別的な威信が与えられるということである。
- 責任と報酬の合理的なバランスを維持するために重視する報酬の種類が社会によって大きく異なる。
7. したがって、希少財や希望する財の量や、それらが受ける威信や尊敬の量において、異なる階層間の社会的不平等は、いかなる社会においても、積極的に機能するものであり、必然的なものである。
- ここまでの議論からすれば、不平等の分配にすべきなのは権力と財産だけであると述べてもよいはずなので、威信と尊敬の差異を引き合いに出す必要はない。
(権力や財産に関係なく)「一人一人の人間が適切な仕事を良心的にこなす限り、一人一人の人間は他のすべての人間と同じように社会的に価値がある」という考えは、不可能であるとは限らない。
社会階層の逆機能(dysfunction)とは
コメント
- 「社会的閉鎖」「地位の非一貫性」「メリトクラシー」など、そのような語が直接使われているわけではないが、社会階層論のエッセンスが詰まった論文と感じた。特に職業による交渉力の違いは、後続の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.
- 伝統的な階級分析に対する批判を行い、階級分析を再び方向づけるような形で再構築するのが本稿の狙い
- 階級分析の批判者が採用するアプローチ
- 階級分析の分析的な軸
- 実質 vs 名目 / 連続的 vs. 離散 / 集約的 vs. 非集約的
- 著者らは名目・離散・非集約的の立場を取る
- 分業
- 技術的分業概念の誤解:分業における機能的なグループ化は名目的なものであり、したがって、社会的な行動や識別の意味のある基盤を構成する社会的なグループ化になる可能性は低い
- 現代の傾向は、一方では職業的なグループ化と他方では「タスク・ニッチ」の間の動的なマッチング・プロセスの結果として分業を扱うこと
- ある職業は、法的・政治的・経済的な闘争の結果である
- アイデンティティ…自己認識
- アウェアネス…他者認識
- 社会的閉鎖
- 単位職業レベルでの集団行動の 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)
- 出力されるのはこんな感じの画像になります。
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)
{gnm}を使ったクロス表の分析
【2021/03/12更新:p値をカイ2乗値から計算していましたがdeviance由来に修正しました】
- 最近は対数線形・対数乗法モデルの復習をしています。
- 色々と読み返してはいるのですが、以下の本は簡潔にまとまっており、非常に勉強になりました。
- オッズ比から始まって、RC(M)-L modelまで取り扱っています。
- 今回は備忘録も兼ねて、同書のExample2.2をRの{gnm}パッケージを使って一部再現しようと思います。
- Rでの対数線形・対数乗法モデルの実装方法に関しては、あまりまとまった日本語の資料がないようでした。
- モデル自体の解説は日本語でもすぐに資料が見つかると思います。
データの用意
- 同書に記載ある通り、学歴(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
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}
参考: