SNP とかなんでもいいのだが、行列データがあって、ある列のデータのうち条件をみたすものだけを抽出して、和を取りたい。
それをR とかPython を使わずに、シェルというかawk で完結したいのだが、という悩みを同僚が言ってきたのでやってみた。
一発でsum みたいな関数で和が出るわけではないので、必要な列を取る > 条件分岐する > increment で足す > 最後にprint する、という感じでやればこんな感じ。
awk で変数を引数にとるには -v オプションを使えばいいので、シェル芸人できる。
サンプルデータの作成にはR でワンライナーを使った。
R -q -e 'write.table(matrix(ceiling(runif(10*20, 1, 1000)), 20), "testmat.txt", quote=FALSE, row.names=FALSE, col.names=FALSE)' cat testmat.txt awk '{if($2 > 800) total = total + $2};END{print total}' testmat.txt
サンプルデータはこんな感じで
283 362 409 13 703 991 907 765 932 947 790 141 739 100 356 795 169 650 635 747 267 531 53 891 587 273 821 164 124 548 465 332 425 431 377 761 125 316 901 495 636 139 424 736 777 152 793 143 282 908 367 335 568 468 377 478 79 38 471 395 12 773 929 556 418 503 539 305 210 348 265 584 193 211 184 72 346 967 343 212 981 727 444 324 300 511 773 549 453 607 37 87 892 808 538 413 837 746 471 51 798 488 798 810 952 682 74 38 826 21 576 985 498 788 571 671 683 930 39 335 278 413 154 409 413 155 807 523 513 545 104 30 257 455 979 232 415 935 174 258 962 993 59 291 8 809 243 793 430 47 782 17 465 925 483 109 740 250 782 804 578 51 265 666 40 991 211 476 964 353 110 730 443 805 580 373 498 276 832 524 438 188 327 638 260 664 478 810 256 59 888 387 781 425 747 905 783 472 824 274
全然イケてないけどR のワンライナーで検算すれば
R -q -e 'sum(read.table("testmat.txt")[read.table("testmat.txt")[,2]>800,2])'
Python で書けば
python -c "import numpy as np; a=np.loadtxt('testmat.txt'); print(np.sum(a[np.where(a[:,1]>800),1])) "