0. はじめに

このページはKAKENHIデータベースからダウンロードできるCSVファイルの「研究分担者」列をキレイにする方法を紹介していきます。具体的には、複数人の研究者情報が格納されている場合に研究分担者が1人1行になるように展開していきます。


このようなデータを

このようにします。


1. 下準備

必要なパッケージは以下の通りです。個人情報が多いため、サイト上では結果を表示させませんが、2019年度の採択課題を想定して進めていきます。

# パッケージの読み込み
library(data.table)   # 高速なデータインポートのため
library(dplyr)        # データの整理のため
library(DT)           # 集計表の出力のため
library(stringr)      # 文字列操作のため
library(tidyr)        # 入れ子構造の解除のため

# インストールされていない場合は、以下のコマンドの「#」を外して実行
# install.packages("data.table")
# install.packages("dplyr")
# install.packages("DT")
# install.packages("stringr")

d <- fread("kaken_2019_20191201.csv")


2. パターンの確認

まず、研究分担者列に入っている値の形式を確認しておきます。基本的には研究代表者と同様の形式で値が格納されていますが、研究分担者が複数いる場合には「\n」によって区切られているようです。

d %>% 
  select("研究分担者")  %>%       # 研究分担者列のみ抽出
  filter(研究分担者 != "") %>%    # 研究分担者が空白ではない行のみ抽出
  head()                          # 最初の5                          


3. 研究分担者列の展開

研究分担者列を1人1行に展開するために、以下の2つのステップを経ることにします。言葉で説明しても何のことかよく分からないと思うので、とにかく実行していきます。


1. 「\n」を区切りに複数の研究分担者を分割(「\n」を含まない値はそのまま)
2. 分割された値がそれぞれ1行となるように縦に展開(残りの列は全てコピー)


3.1. 研究分担者の分割

文字列の分割にはstringrパッケージのstr_split関数を用います。以下のコードでは「研究分担者」列の値を分割し、「研究分担者2」列に格納しています。なお、結果については擬似的なデータを用いた結果を表示しています。

d <- d %>%
  
  # 研究代表者と研究分担者の列のみ抽出
  select(研究代表者, 研究分担者) %>%
  
  # 研究分担者が含まれる行のみ抽出
  filter(研究分担者 != "") %>%
  
  # 「\\n」を区切りに研究分担者の値を分割し、研究分担者2列に格納
  mutate(研究分担者2 = str_split(研究分担者, "\n"))

# 研究分担者2列の最初の5行のみを表示
d %>% select(研究代表者, 研究分担者, 研究分担者2) %>% head()

上の表を見ても研究分担者列と研究分担者2列に違いはないように見えますが、その中身は大きく異なっています。

以下のコードは研究分担者2列だけ取り出して中身を確認しています。結果の[[1]]や[[2]]は行番号と対応しており、研究分担者が分割されて格納されていることがわかると思います。

d %>% 
  .$研究分担者2 %>%    # 研究分担者2列の取り出し
  head()                # 最初の5つの値のみ取り出し(※以下の擬似的な結果では2つだけ)
## [[1]]
## [1] "C山 C介 CC大学, CC学部, 教授 (XXXXXXXX)"    
## [2] "D本 D子 DD大学, DD研究所, 准教授 (XXXXXXXX)"
## 
## [[2]]
## [1] "E川 E江 EE大学, EE学部, 助教 (XXXXXXXX)"  
## [2] "F沢 F郎 FF大学, FF研究所, 教授 (XXXXXXXX)"


3.2. 入れ子構造の解除

上記の通り、研究分担者2列は、それぞれの値の中に更に値が格納されているという入れ子構造をなしています。この入れ子構造を解除することによって、研究分担者の列を縦方向に展開することができます。

この処理を行ってくれるのがtidyrパッケージのunnest関数です(逆に入れ子構造を作る場合にはnest関数)。

d <- d %>%
  select(研究代表者, 研究分担者) %>%
  filter(研究分担者 != "") %>%
  mutate(研究分担者2 = str_split(研究分担者, "\n")) %>%
  
  # 入れ子構造を解除  
  unnest()

# 研究分担者2列の最初の5行のみを表示
d %>% select(研究代表者, 研究分担者, 研究分担者2) %>% head()

今回は生の処理結果をお見せできなかったので分かりづらかったと思うのですが、是非、ご自分のPCで試してみてください。