CSVは何らかのデータを保持する目的で使われることが多い。CSVデータそのものを編集して作成するというよりは、何らかのデータをCSVの状態で受け取り、そのデータを分析したり利用したりすることのほうが多いわけだ。

CSVのプラグインである「chrisbra/csv.vim」には、CSVデータを分析するための基本機能がいくつか用意されている。その総数はスプレッドシートアプリケーションほど豊富ではないが、提供されている機能だけでもかなりのことができる。今回はこの操作方法を紹介しよう。

CSVファイルを開いているところ

なお今回は、総務省が2015年に調査を実施し2017年に公開した国勢調査データ「統計局ホームページ/平成27年国勢調査/調査の結果」のうち、集計地域区分が全国のものを使用した。CSVデータに数値データだけではなく注釈が含まれているのでこれを削除したほか、都道府県別の小計データを抜いたデータを使っている(小計データはchrisbra/csv.vimの機能で計算するため)。

列データを分析するCSVAnalyze

chrisbra/csv.vim」で最も便利な機能の一つが「CSVAnalyze」だ。同機能では、指定した列、またはカレント列のデータを分析して、どのデータが何個そして何%存在しているのかを表示する。

CSVAnalyzeの実行例

データが論理値(True/False)になっている場合、どちらがどの程度の割合で存在しているのか知りたいことがある。そうした場合、CSVAnalyzeで分析するとその割合が一発でわかる。

またこの機能は例外データを知りたい場合などにも役に立つ。「ほとんどのケースである値に収まるものの、いくつかのレコードに例外的なデータが含まれている」という場合(こういったケースは結構多い)、そのレコードを突き止めたいとき、CSVAnalyzeを使うとすぐに分析できる。

CSVAnazlyzeの動作速度は対象とするCSVファイルのサイズなどに依存するため、100MB以上になってくると多少もたつきを感じるようになると思う(当然、使用している環境のスペックにもよる)。だが、それでも使ってしまうほど、CSVAnazlyzeは便利なのだ。

合計値、最大値、最小値、平均値

数値データの場合には列や行ごとに値の合計値を計算したり、特定の範囲内データの合計値を計算したりすることもある。chrisbra/csv.vimでは、「CSVSumCol」で列の合計値を計算することができる。

例えば、次のスクリーンショットは特定の行範囲の5列目の合計値を計算する様子だ。範囲をビジュアル選択で選んだ後で「:CSVSumCol 5」だ。選択した範囲の5列目のデータが計算される。

ビジュアル選択した範囲に対して「CSVSumCol」で合計値を計算

計算したのは平成22年度に実施された国勢調査の結果で、合計値は調査時点での日本の総人口を表している。計算結果によれば1億2,700万人ほどということになる。

これを5年後に実施された国勢調査の結果に対して実施すると次のようになる。

平成27年度のデータに対して同じように合計値を計算

平成27年度は1億2,560万人ほど

平成27年度の総人口は1億2,560万人ほどなので、平成22年度から平成27年度にかけてざっくり140万人ほど総人口が減ったということになる。ビジュアル選択をしてその場で分析できるので結構便利だ。なお、列方向ではなく行方向に対して合計値を求める場合には「CSVSumRow」を利用する。

列方向に最大値や最小値を知りたいことも多い。これは「CSVMaxCol」および「CSVMinCol」で実施できる。操作方法は「CSVSumCol」と同じだ。範囲を指定すれば、その範囲内での最大値および最小値を調べることができる。それぞれ使用例を次に示す。

ビジュアル選択で範囲を絞った上で「CSVMaxCol」で列の最大値を求める

最大値順に値が表示されている

ビジュアル選択で範囲を絞った上で「CSVMinCol」で列の最小値を求める

最小値順に値が表示されている

合計値とともに平均値もよく使われる。操作方法はこれまでと同様で、コマンドとしては「CSVAvgCol」で実施できる。使用例は次の通りだ。

「CSVAvgCol」で平均値を計算できる

「CSVAvgCol」で平均値を計算した結果

前々回、データを転置(縦と横を入れ替える)する機能として「CSVTranspose」を取り上げた。上記では列データに対して処理が行われているわけだが、CSVTransposeコマンドで転置すれば、行だったデータは列になるので、同じようにデータを処理することができる。

データのバイト数/レコード数を調べる

文字列データを扱っている場合など、データのバイト数が最大でどれくらいあるかを知りたいことがある。そうした場合には「CSVColumnWidth」を使うと、その列の最大のバイト数を調べることができる。

CSVColumnWidthコマンドの実行サンプル

レコード数(行数)を知りたいという場合には「CSVCountCol」を使用する。ヘッダが指定されている場合、ヘッダを除いた行数がレコード数として表示される。

CSVCountColコマンドの実行例

chrisbra/csv.vimにはこれ以外にも標準偏差などを計算するコマンドが用意されている。標準偏差を利用するのであれば、統計処理専用のプログラミング言語か、汎用プログラミング言語+専用ライブラリの組み合わせを利用し始めたほうがよいような気もするが、一応chrisbra/csv.vimでもごく簡単な標準偏差は計算できるようになっている(PopVarCol、SmplVarCol、PopStdCol、SmplStdCol)。

使い方は人それぞれだが、CSVAnalyzeは便利

結局、頻用する機能は用途に依存するが、いずれにせよCSVAnalyzeは非常に手軽で便利である。

こうした機能はスプレッドシートアプリケーションには当然のように実装されているが、Vimおよびchrisbra/csv.vimで話が済むのがとにかく楽だ。スプレッドシートアプリケーションを起動する必要がないし、サーバにログインした状態で作業が完結する。特にCSVデータを業務で使うことが多い方にとって、chrisbra/csv.vimは習得する価値のあるだろう。

本連載で使っている~/.vimrcファイル

本連載で使っている設定ファイル(~/.vimrc)は以下の通りだ。

"dein Scripts=============================
if &compatible
  set nocompatible               " Be iMproved
endif

" Required:
set runtimepath+=~/.cache/dein/./repos/github.com/Shougo/dein.vim

" Required:
if dein#load_state('~/.cache/dein/.')
  call dein#begin('~/.cache/dein/.')

  " Let dein manage dein
  " Required:
  call dein#add('~/.cache/dein/./repos/github.com/Shougo/dein.vim')

  " Add or remove your plugins here
  call dein#add('junegunn/seoul256.vim')
  call dein#add('vim-airline/vim-airline')
  call dein#add('vim-airline/vim-airline-themes')
  call dein#add('preservim/nerdtree')
  call dein#add('tpope/vim-commentary')
  call dein#add('tpope/vim-fugitive')
  call dein#add('fholgado/minibufexpl.vim')
  call dein#add('dense-analysis/ale')
  call dein#add('junegunn/fzf', {'build': './install --all'})
  call dein#add('junegunn/fzf.vim')
  call dein#add('sheerun/vim-polyglot')

  " Required:
  call dein#end()
  call dein#save_state()
endif

" Required:
filetype plugin indent on
syntax enable

" If you want to install not installed plugins on startup.
if dein#check_install()
  call dein#install()
endif

" seoul256
let g:seoul256_background = 233
colo seoul256

" vim-airline
let g:airline_powerline_fonts = 1
let g:airline_theme = 'molokai'

" NERDTree
"  <C-o> open NERDTree
nnoremap <silent> <C-o> :NERDTreeToggle<CR>

" minibufexpl
nnoremap <silent> bn :<C-u>:bnext<CR>
nnoremap <silent> b1 :<C-u>:b1<CR>
nnoremap <silent> b2 :<C-u>:b2<CR>
nnoremap <silent> b3 :<C-u>:b3<CR>
nnoremap <silent> b4 :<C-u>:b4<CR>
nnoremap <silent> b5 :<C-u>:b5<CR>
nnoremap <silent> b6 :<C-u>:b6<CR>
nnoremap <silent> b7 :<C-u>:b7<CR>
nnoremap <silent> b8 :<C-u>:b8<CR>
nnoremap <silent> b9 :<C-u>:b9<CR>

" fzf
nnoremap <silent> fzf :Files<CR>
nnoremap <silent> ls :Buffers<CR>

"End dein Scripts=========================

set number
syntax on
set whichwrap=b,s,[,],<,>,~,h,l
set cursorline
set incsearch
set hlsearch
set ignorecase

付録 chrisbra/csv.vim 操作・設定方法まとめ

コマンド 内容
CSVWhatColumn カーソルが何列目にあるか
CSVWhatColumn! 同列1行目の内容を表示
CSVNrColumns 最大列数を表示(先頭から10行で判断)
CSVSearchInColumn /パターン/ 現在の列をパターンで検索
CSVSearchInColumn 列番号 /パターン/ 指定した列をパターンで検索
CSVHiColumn 現在の列を強調表示
CSVHiColumn 列番号 指定した列を強調表示
CSVHiColumn! 列の強調表示を解除
CSVArrangeColumn テーブル形式での表示へ切り替え(実験的機能)
CSVTabularize テーブル形式でのプレビュー表示
CSVDeleteColumn 現在の列を削除
CSVDeleteColumn 列番号 指定した列を削除
CSVHeader 1行目を別ウィンドウで表示
CSVHeader 行数 先頭から指定行数分を別ウィンドウで表示
CSVHeader! 開いた行ヘッダウィンドウを閉じる
CSVVHeader 1列目を別ウィンドウで表示
CSVVHeader 列番号 行頭から指定列数分を別ウィンドウで表示
CSVVHeader 開いた列ヘッダウィンドウを閉じる
CSVSort 現在の列でファイルをソート
CSVSort 列番号 現在の列でファイルをソート
CSVSort! 現在の列でファイルを逆順にソート
CSVSort! 列番号 現在の列でファイルを逆順にソート
CSVColumn 現在の列をコピー
列番号CSVColumn 指定した列をコピー
CSVMoveColumnor 現在の列を最後の列の右側へ移動
CSVMoveColumn 列番号 列番号 最初に指定した列を、2つ目に指定した列の右側へ移動
CSVSumCol 現在の列の合計を出力
CSVSumCol 列番号 指定した列の合計を出力
CSVSumRow 行の合計を出力
CSVNewRecord 新しい行を作成
CSVNewDelimiter デリミタ 区切り文字を変更
CSVConvertData データをほかの形式に変換
CSVDuplicates 列番号 指定した列で重複している行を出力
CSVAnalyze 現在の列を分析する(値とその数、割合など)
CSVAnalyze 列番号 指定した列を分析する(値とその数、割合など)
CSVVertFold 1列目から現在の列を折りたたむ
CSVVertFold 列番号 1列目から指定した列までを折りたたむ
CSVVertFold! 列の折りたたみを解除する
CSVTranspose 列と行を入れ替える(転置)
CSVAddColumn 現在の列の右側に新しい列を追加
CSVAddColumn 列番号 指定した列の右側に新しい列を追加
CSVDupColumn 現在の列を右側に複製
CSVDupColumn 列番号 指定した列を右側に複製
CSVSubstitute 列番号/パターン/文字列/ 指定した列で置換
CSVColumnWidth 列ごとの最大文字数を出力
CSVCountCol 現在の列内の値の数を出力
CSVCountCol 列番号 指定した列内の値の数を出力
CSVMaxCol 現在の列内の最大値を出力
CSVMaxCol 列番号 指定した列内の最大値を出力
CSVMinCol 現在の列内の最小値を出力
CSVMinCol 列番号 指定した列内の最小値を出力
CSVAvgCol 現在の列内のデータの平均値を出力
CSVAvgCol 列番号 指定した列内のデータの平均値を出力
PopVarCol 現在の列の母集団分散を出力
PopVarCol 列番号 指定した列の母集団分散を出力
SmplVarCol 現在の列の標本分散を出力
SmplVarCol 列番号 指定した列の標本分散を出力
PopStdCol 現在の列の母標準偏差を出力
PopStdCol 列番号 指定した列の母標準偏差を出力
SmplStdCol 現在の列の標本標準偏差を出力
SmplStdCol 列番号 指定した列の標本標準偏差を出力
移動キー 内容
「Ctrl」+「→」 右の列へ移動
L 右の列へ移動
W 右の列へ移動
「Ctrl」+「←」 左の列へ移動
E 左の列へ移動
H 左の列へ移動
列を上へ移動
K 列を上へ移動
列を下へ移動
J 列を下へ移動
フィルタキー 内容
↩️ 現在の列と一致しないすべての行を動的に折りたたむ
Space 現在の列と一致するすべての行を動的に折りたたむ
BS 動的フィルタから最後のアイテムを削除
設定項目 内容
g:csv_delim デフォルトのデリミタ
g:csv_no_conceal 「1」に設定するとデリミタ部分を「|」で視覚的に表示(デフォルトは設定されていない)
g:csv_highlight_column 「’y’」に設定するとカーソルがある列を自動でハイライト
b:csv_headerline ヘッダの行数を指定。「0」を指定するとヘッダとしてのハイライトが行われなくなる