# README.md


- ここには書いてないことについて
    - 文字コードや改行コードの説明もしません。
    - `cpanm`の解説はあまりしません(`cpanm`はCPANモジュールのインストーラーです)。
    - 一般的なUNIX系コマンドも、そのインストールの仕方の説明もしません(nkfとかshufとか)。
    - シェル(bashとかzshとか)は何かも説明しません。パイプ、リダイレクション、プロセス置換も同様です。
    - `man hier`を見ると、`/var/passwd`のことなど分かって良いかも知れません。
- おそらく、UNIX系のコマンドを使いつつデータ分析をしている人には、読みやすいとは思いますが、そうでない場合はその限りではないかもしれません。ここに書いたプログラムを逐次実行すると、意味が段々わかってくると思います。



# 記載したコマンドラインについての注意事項

- bash と zsh のどちらのシェルでも動きます。
- 下記は1行ずつ実行することを想定しています。**複数行をコピペして実行すると不具合が起こるかもしれません。**
- 別に最初から順に実行しなくても良いです。途中の、適当な区切りから始めても大体の場合は動作します。
- コマンドは詳しく解説しません。実際に実行してみて、理解に努めると良いと思います。

- シェルプログラミングで、**パイプ**("|"の1文字)でコマンドをつなぐことを、下記でよく使います。
- プロセス置換も下記でよく使います。
- **プロセス置換の例** : `tail <(seq 20)` これは`seq 20`の結果がまるでファイルとして`tail`に渡されます。
- シェルスクリプトの関数も使います。`newfunc (){ .... }` のようにして定義します。

- zsh で`#`以降をコメント扱いにならない場合は、次のコマンドの実行をお願いします。

```
setopt interactivecomments
# ↑ この上記のコマンド1行を実行することで、zshにおいて # より後ろが bash のようにコメントと見なされる。
# ↑ もしも上記を解除したくなった場合は unsetopt interactivecomments
```

### 本レポジトリコマンドを別個にインストールする方法

```
cpanm App::csv2tsv #←Text::CSVに依存. 約20秒
cpanm App::expandtab #← Text::VisualWidthに依存
cpanm App::colsummary # 残りは、それぞれ約2秒で完了
cpanm App::venn # モジュール名はApp::コマンド名
cpanm App::csel # アンインストールの時は -U を使う↓
cpanm App::crosstable # 例. cpanm -U App::csel
cpanm App::freq # cpanm -vでインストール詳細を表示
cpanm App::digitdemog
```


### CSV形式からTSV形式に変換する(csv2tsv)

ここではCSV形式のデータの例として、厚生労働省のサイトの「オープンデータ」の「**PCR検査実施人数**」のデータと、
内閣府ホームページの「**国民の祝日について**」(**昭和30年（1955年）から令和4年（2022年）国民の祝日**)を取得し、
それをTSV形式に変換します。

1. ここで用いるデータに関して:
- 出典：厚生労働省ホームページ https://www.mhlw.go.jp/stf/covid-19/open-data.html
- この出典の記載の書き方は右に従った。https://www.mhlw.go.jp/chosakuken/index.html
- 2021年6月20日(日)現在の情報である。

```
cpanm App::csv2tsv
wget  https://www.mhlw.go.jp/content/pcr_case_daily.csv
less pcr_case_daily.csv
csv2tsv < pcr_case_daily.csv > pcr_case_daily.tsv
# (現状 リダイレクションの"<" は省略すると動作が終了しない不具合が発生する場合があります。)
less -x25 pcr_case_daily.tsv
# less はオプション -x でタブ区切りの桁の間隔を調整できます。
# less を実行中の時でも、"-x"の2文字を打鍵して、さらに数値を入力すると、調整ができます。
```


2. ここで用いるデータに関して:
- 出典：内閣府ホームページ https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html
- この出典の記載の書き方は右に従った。https://www.cao.go.jp/notice.html
- 2021年6月20日(日)現在の情報である。

```
cpanm App::csv2tsv
wget  https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv
file syukujitsu.csv # → Non-ISO extended-ASCII text, with CRLF line terminators
nkf syukujitsu.csv | less
nkf syukujitsu.csv | csv2tsv > syukujitsu.tsv
less -x25 syukujitsu.tsv
```

### 列を縦に揃えて表示する機能(expandtab)

```
cpanm App::expandtab # 約8秒. Text::VisualWidthに依存
tr ":" "\t" < /etc/passwd | expandtab | less -NS
sed 1,10d /etc/passwd | expandtab -i: -b. | less -NS
```

### 全各列の特徴をコンパクトに表示(colsummary)

1. /etc/passwdを使う例

```
colsummary -i: <( grep -v -e '^#' /etc/passwd )
```

2. インターネット上の「TRC新刊図書オープンデータ」 から、データをダウンロードして、下記の様な
コマンドラインを実行する。ファイル名は適宜日付の部分などは違ってくるであろう。
なおのこのサイトには、「この書誌情報は、営利・非営利を問わず、利用手続きなしでご自由にご利用いただけます」と記載があった(2021年6月20日(日)現在)。

```
cpanm App::colsummary # 約2秒
unzip TRCOpenBibData_20210605.zip # zipファイルを解凍
ln -s TRCOpenBibData_20210605.txt 0605.txt
colsummary -v9 -g3 -m0 0605.txt | expandtab -s30
```

3. 国民の祝日のデータを使った例

```
nkf syukujitsu.csv | tr "/," "\t\t" | sed 1d | ~/bin4tsv/*/colsummary | expandtab
```

上記↑の出力はこうなる↓

```
cpos diff ave.     range               frequent                                              frequency~lower(multi)                                       digits
1    68   1992.323 1955~2022           2019|2018|2001|2007|1996|1990                         22|20|19(4)|18(3)|17(11)|16(8)~14(7)|13(6)|12(8)|11|10|9(10) 4
2    12   6.104    1~12                5|11|1|9|4|3                                          185|151|147|138|78|74|67|60|35|30|9|1                        1~2
3    25   13.618   1~30                23|3|15|11|1|5                                        161|136|87|70|69|68(2)~10|9|8(3)|7|6(3)|5                    1~2
4    23   0.000    こどもの日~結婚の儀 休日|こどもの日|勤労感謝の日|文化の日|憲法記念日|元日 104|68(8)|67|57|56|53~27|16|7|3|2(2)|1(3)                    2~12
```

4. PCR検査実施人数の例

```
colsummary -= -i, pcr_case_daily.csv | expandtab
# -= で 1行目を列名の並びと見なし、データの値と見なさない。
# -i, により入力の区切り文字を(タブ文字ではなくて)コンマ文字(,)に変更している。
```

上記↑の出力はこうなる↓

```
cpos diff ave.      name                   range              frequent                                                      frequency~lower(multi)             digits
1    487  2020.347  日付                   2020/10/1~2021/6/9 2020/8/21|2020/7/19|2020/7/24|2020/5/10|2020/10/26|2020/11/11 1(487)                             8~10
2    85   24.988    国立感染症研究所       0|1~517            0|20|8|3|18|36                                                354|6(2)|5|3(6)|2(23)|1(52)        1~3
3    178  222.912   検疫所                 0|1~1733           0|1|13|4|11|3                                                 257|12|5(2)|4(2)|3(3)|2(22)|1(147) 1~4
4    474  3910.355  地方衛生研究所・保健所 398~11856          2425|867|4678|2502|6314|1326                                  2(13)|1(461)                       3~5
5    471  20647.676 民間検査会社           ~0|2~89005         0|37|28|3651|11|5                                             9|2(8)|1(462)                      0|1~5
6    453  1974.018  大学等                 ~0|4~6367          0|1012|4766|558|650|3924                                      14|2(21)|1(431)                    0|1~4
7    455  7567.082  医療機関               |9~35210           |430|543|1808|795|10649                                       18|2(15)|1(439)                    0|1~5
```

上記の`colsummary`の出力の例として現れたave.は数値としての平均である(数で無い入力値は0として計算する)。この出力列は `-m 0`というオプションで抑制できる。`expandtab`で半角空白文字で出力のタブ文字を変換して縦に揃うようにしたが、`expandtab`をしないとそのままエクセル等の表計算ソフトに直接コピペが出来るようになる。

### 複数ファイルの行データの重なりを見る(venn)


4個のプロセス置換でデモ:

```
cpanm App::venn
function y(){ echo -n $* | perl -pe's/./$&\n/g' }
perldoc List::Util # qキーで終了. minstrとmaxstrを参照
venn <(y ABCCCC) <(y AABDEF) <(y ABBDEF) <(y DEEEF)
```

上記の出力↓

```
cardi. file1  file2  file3  file4  minstr maxstr
2.     2      3      3      0      'A'    'B'
1.     4      0      0      0      'C'
3.     0      3      3      5      'D'    'F'
```

### 列をいろいろ操作(csel)

```
cpanm App::csel
# ↑ コマンド csel をインストール。
perl -E'say join"\t",1..12' | tee c12.tsv
# 1   2   3   4   5   6   7   8   9   10  11  12  
awk '{print$3,$4,$5,$6,$7}' c12.tsv # AWKの例
# 3 4 5 6 7
csel -p 3..7 c12.tsv # cselはAWKより簡単
# 3   4   5   6   7
csel -d3..7,10,12 c12.tsv # -dで抑制(AWKだと難)
# 1   2   8   9   11
csel -h12..10 c12.tsv     # -hで先頭(左)へ移動
# 12  11  10  1   2   3   4   5   6   7   8   9
csel -t9,6 c12.tsv        # -tで末尾(右)へ移動
# 1   2   3   4   5   7   8   10  11  12  9   6
```

### クロス集計(crosstable)

```
cpanm App::crosstable
```

1. 祝日の例

```
awk -F/ 'NR>1{print $2"\t"$1}' syukujitsu.csv | crosstable | csel -p1,-43..-1 | expandtab
```

上記の出力↓ (6月は通常休日はないが、1993年にはあった。)

```
X1*X2 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022
1     2    2    2    2    4    2    2    2    2    4    2    2    2    2    2    4    2    2    2    2    2    2    2    2    2    2    3    2    2    2    2    2    3    2    2    2    2    3    2    2    2    2    2
2     1    1    1    1    1    1    1    1    1    2    2    1    1    1    1    1    2    1    1    1    1    2    1    1    1    1    1    2    1    1    1    1    1    1    1    1    1    1    2    1    3    2    2
3     1    1    2    1    1    1    1    1    2    1    1    1    1    1    1    1    1    1    1    2    1    1    1    1    1    2    1    1    1    1    2    1    1    1    1    1    2    1    1    1    1    1    1
4     1    1    1    1    2    1    1    1    1    1    2    1    1    1    1    1    1    1    1    1    1    2    1    1    1    1    1    2    1    1    1    1    2    1    1    1    1    1    2    2    1    1    1
5     2    3    2    2    2    3    2    3    3    3    3    4    3    3    3    3    4    2    3    3    3    3    4    2    3    3    3    3    4    4    3    3    3    4    4    4    3    3    3    6    4    3    3
6     0    0    0    0    0    0    0    0    0    0    0    0    0    1    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
7     0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    1    2    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    2    2    1
8     0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    1    1    1    2    1    2    1
9     2    2    2    2    3    3    2    2    2    2    3    3    2    2    2    2    3    2    2    2    2    3    3    2    2    2    2    3    2    3    2    2    2    2    2    3    2    2    3    2    2    2    2
10    1    1    2    1    1    1    1    1    1    1    1    1    1    2    1    1    1    1    1    2    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    1    2    0    0    1
11    3    2    2    2    2    3    3    2    2    2    3    3    2    2    2    2    3    3    2    2    2    2    3    3    2    2    2    2    3    2    2    2    2    3    3    2    2    2    2    3    2    2    2
12    0    0    0    0    0    0    0    0    0    1    2    1    1    1    1    1    1    1    1    1    1    2    1    1    1    1    1    2    1    1    1    1    2    1    1    1    1    1    2    0    0    0    0
```


### 頻度表の作成(freq)

```
cpanm App::freq # まだインストールしていない場合
# cpanm -U App::freq でアンインストールも可能。
```

1. 休日のデータを使った例:

```
awk -F/ 'NR>1{print $1}' syukujitsu.csv | freq -~ -a | head
# このfreqは対象となる値の辞書式順序で元々出力するが、
# -~ の指定によりそれが逆順になる(2022年から1955年に向かって表示する)。
# -a で頻度の累積和も表示する。
# headコマンドで先頭の10行のみ見せる。
```

上記の出力↓

```
Freq*   AccSum  LinStr
16      16      2022
17      33      2021
18      51      2020
22      73      2019
20      93      2018
17      110     2017
17      127     2016
17      144     2015
17      161     2014
```

2. 休日のデータ(休日の多かった年の順に表示)

```
awk -F/ 'NR>1{print $1}' syukujitsu.csv | freq  -f -~ -a | head -7
# このfreqは対象となる値の辞書式順序で元々出力するが、
# -f の指定を追加したことで、頻度の少ない順であり、-~ でその逆順になる。
# -a で頻度の累積和も表示する。なお、これらのオプションの順序は演算に影響しない。
```

上記の出力↓

```
Freq*   AccSum  LinStr
16      16      2022
17      33      2021
18      51      2020
22      73      2019
20      93      2018
17      110     2017
```

### 全行で各文字がどの桁に何個(digitdemog)

```
digitdemog <( csel -p11 TRCOpenBibData_20210605.txt ) | expandtab
# 上記の結果は下記のようになる↓
    1   2   3    4    5    6  7  8  9
'.' 0   0   0    0    3    0  0  0  0
'0' 0   137 0    0    3    0  0  0  0
'1' 385 313 0    4    0    0  0  0  0
'2' 666 59  0    10   4    0  0  0  0
'3' 118 16  0    4    1    0  0  0  0
'4' 3   6   0    0    0    0  0  0  0
'5' 0   90  0    0    2    3  0  0  0
'6' 0   208 0    0    4    0  0  0  0
'7' 0   21  0    0    1    0  0  0  0
'8' 0   69  0    3    0    0  0  0  0
'9' 0   253 0    0    3    0  0  0  0
'c' 0   0   1151 0    0    18 3  0  0
'm' 0   0   0    1151 0    0  18 3  0
'×' 0   0   21   0    0    0  0  0  0
end 80  0   0    0    1151 0  0  18 3
```

`digitdemog -L2`で具体例を抽出。

```
digitdemog -L2 <( csel -p11 TRCOpenBibData_20210605.txt ) | expandtab
# 上記の結果は下記のようになる↓
length freq minstr       maxstr
0      80   ''           <-- same
4      1151 '11cm'(2)    '43cm'(3)
7      18   '12×12cm'(2) '27×39cm'(2)
8      3    '18×8.5cm'   <-- same
```

`digitdemog -.`を使う。

```
digitdemog -. <( csel -p11 TRCOpenBibData_20210605.txt ) | expandtab
# 上記の結果は下記のようになる↓
    1   2   3     4     5     6   7   8   9
'.' 0   0   0     0     3.    0   0   0   0
'0' 0   137 0     0     3     0   0   0   0
'1' 385 313 0     4     0     0   0   0   0
'2' 666 59  0     10    4     0   0   0   0
'3' 118 16  0     4     1     0   0   0   0
'4' 3   6   0     0     0     0   0   0   0
'5' 0   90  0     0     2     3.  0   0   0
'6' 0   208 0     0     4     0   0   0   0
'7' 0   21  0     0     1     0   0   0   0
'8' 0   69  0     3.    0     0   0   0   0
'9' 0   253 0     0     3     0   0   0   0
'c' 0   0   1151. 0     0     18. 3.  0   0
'm' 0   0   0     1151. 0     0   18. 3.  0
'×' 0   0   21    0     0     0   0   0   0
end 80  0   0     0     1151. 0   0   18. 3.
```
