DPCチェッカー0.08 デザインをちょっと修正
例によってこちらからどうぞ。
バージョン0.08の変更点:デザイン修正
これを書いている人間は、残念ながら「デザイン」とか「絵心」というものは皆無です。
ということでGoogle様のMaterial Design Liteに乗っかりました。
といっても所々昔のままで、ツギハギ感がひどいですが、ドキュメント読み始めてまだ数時間なので…
しかしこういうデザインテンプレートがオープンソースで山ほど転がってるのが、Web技術のいいところです。
デスクトップ向けのUIだと、あんまりこういうのは見つからないので…
次回アップデートではようやくグラフ描画機能を追加する予定です。
Flaskの勉強もちょこちょこしてますので、各種の挙動がもう少しマシになると思います。
SQL方言について(ついでにDPCチェッカーにクエリを追加)
SQLの方言
残念なことですが、SQLは実装ごとに方言があります。
私はPostgreSQLばっかりいじってたので気にも留めていませんでしたが、今回DPCチェッカーを作っていて否が応でも気付かざる得ませんでした。
DPCチェッカーは組み込みで配布するため、SQLite3を使っています。exe単体で実行できるSQLで、Pythonには何とビルトインされています。
こちらの実装はPostgreSQLとかなり違っていて、例えば日付データをネイティブで扱うことが出来ません。
そこにさえ目をつむれば、大抵のクエリは走るのですが、今回はここで詰まりました。
select データ識別番号,実施年月日,診療明細名称,SUM(明細点数・金額*行為回数) from etable Where データ区分 = 60 AND (データ識別番号,実施年月日) IN (select データ識別番号,実施年月日 from dtable Where データ区分 = 93) group by データ識別番号,実施年月日,診療明細名称 HAVING SUM(明細点数・金額*行為回数) > 0;
以前このブログで紹介した、DPC期間中に行った検査を探すクエリです。
INを使った相関サブクエリで、「Dファイル上でDPC入院料を算定した患者と日付」に条件に絞る、ということをやっています。
このクエリはPostgresでは走りますが、SQLiteでは走りません。
AND (データ識別番号,実施年月日) IN...
の部分が問題です。
これをAND データ識別番号 IN...
とすると走ります(これでは条件を満たしませんが)。
()でカラムを複数指定するやり方は、行値式というそうで、実装されているSQLは限られています。
(メジャーどころでは、MicrosoftのSQL Serverも対応していないとか)
どんなに頭を悩ましたところで、実装されていないものは走りません。書き方を変えます。
select e.データ識別番号,e.実施年月日,e.診療明細名称,SUM(明細点数・金額*行為回数) from etable AS e Where データ区分 = 60 AND EXISTS (select d.データ識別番号,d.実施年月日 from dtable Where データ区分 = 93 AND dtable.データ識別番号 = etable.データ識別番号 AND dtable.実施年月日 = etable.実施年月日) group by e.データ識別番号,e.実施年月日,e.診療明細名称 HAVING SUM(明細点数・金額*行為回数) > 0;
今度はEXISTS
を使いました。意味合いは違いますが、求める結果は同じです。
Postgresでは走りますので、意気揚々とSQLiteで走らせると・・・答えが返ってきません。
どうやら私がやっつけで書いたクエリに問題があって、Postgresが優しく(見えないところで)始末をつけてくれたのでしょうか。それとも、SQLiteのEXISTS実装にパフォーマンスの問題があるのでしょうか。または、その両方?
前者である可能性が高いですね。
さて困りました。もうちょっとEXISTSについて調べてもいいのですが、手っ取り早いのは以下のクエリです。
WITH d93 AS (select データ識別番号,実施年月日 from dtable Where データ区分 = 93), e60 AS (select データ識別番号,実施年月日,診療明細名称,SUM(明細点数・金額*行為回数) AS 出来高金額 from etable Where データ区分 = 60 group by データ識別番号,実施年月日,診療明細名称 HAVING SUM(明細点数・金額*行為回数) > 0) select d93.データ識別番号,d93.実施年月日,e60.診療明細名称,e60.出来高金額 from d93 INNER JOIN e60 USING(データ識別番号,実施年月日);
WITH句でテーブルを2つ作ってINNER JOIN
でくっつけています。
結局、今回やりたいのは「検査を行った患者とその日付」の集合と、「DPC入院料を算定した患者とその日付」の積を求めること、つまり二つの集合の共通集合を導き出すことです。
ならばINNER JOIN
で良いわけですね。
(ちなみに、上記のクエリは検査版と注射版を作って、DPCチェッカーに追加しておきました)
DPCチェッカー0.07 : 外部クエリの読み込みに対応しました
例によってこちらからどうぞ。
バージョン0.07の変更点:外部クエリの読み込み機能について
今まで当ツールはコード内部にそのまんまSQLクエリが書いてあるというシロモノでした。
拡張性もへったくれもありませんので、バージョン0.07でSQLクエリは本体から切り離し、query
フォルダに置く形式となっています。
その副産物で、外部クエリの読み込みにも対応出来ました。
お好きなSQL文をquery
フォルダにtxtで置けば、メニューに選択肢が増えます。
なお、エンコーディングはUTF-8にして下さい。
あと幾つかのクエリを追加してあります。 当ブログでも紹介してきましたが、
- EF/Dファイルの区分別集計
- 手術のカテゴリ別金額
- 副傷病分岐なしチェック
です。
本来ならばDPC中に行った検査/注射のチェック機能も追加する筈でしたが、当該のクエリがSQLiteで走りません・・・
移植にはもう少しかかりそうですので、気長にお待ち下さい。
(この件で「SQLクエリの移植」というひどい問題にも出会いました。これは追々記事にします)
今後の課題と予定
見た目がひどい
ほんとにひどい。見づらい。
ということで、多分レイアウト修正をやります。ついでにbootstrapでも勉強するつもりです。
ビジュアライゼーション
かっこいい分析機能とかあるといいですね。こう、どかーんとダッシュボードが開いて、グラフがぬるぬるっとアニメーションして描画されるようなの。
すごい適当なことを書きましたが、こういう機能を楽に実装するなら、もうJavaScriptのライブラリを使うしかありません。
(このブログで紹介したBokehはPythonで動くグラフを作れますが、出力結果はJavaScriptです)
このツールがウェブアプリなのは、私がC#に挫折しただけではなく、グラフ描画にまつわる問題もあるのでした。
まあ、D3.jsみたいなのは他にありませんしね。
DPCチェッカーを0.06にアップデートしました
といっても、csvエクスポート機能をつけただけですが…
例によってこちらからどうぞ。
今後の予定としては
- さっさと外部クエリ読み込みを実装する
- というか今までブログに上げてきたクエリを整理してGitHubにまとめる
- Bokehを使った可視化は業務でやってるので、早めに組み込む
となっております。
如何せん片手間仕事なのでペースは遅いですけど。
もし時間があれば、ロジックをそのまんま流用してJavaScriptで書き直し、Electronでアプリ化したものを配布したいですが、うーん。
今の状況だと難しそうです。
ちなみにPyinstallerを使えば、Pythonのままでexeに出来るのですが、様々なライブラリを全てバンドルしてしまうようで、500MB超にまで膨れ上がります。ソースのサイズを考えると無駄があり過ぎますね。
DPCチェッカー 0.05を公開しました
DPCチェッカー 0.05
いきなりですが、業務の片手間にツールを作ったので公開します。
こちらからどうぞ。
DPCチェッカーはEF/Dファイルを読み込み、出来高対比を算出したり、退院時処方のエラーチェックを行うソフトです。
Flask/Pandas/SQLite3で実装されたウェブアプリケーションで、ブラウザ上で動作しますが、実際にはローカルで動いています。
(初回起動時に、dpc.db
というDBファイルを作成し、そこにデータをストアする仕組み)
こんなのを作ろうと思った経緯
私は普段のDPC分析業務の殆どを、Jupyter Notebook上で行っていますが、それだと他の人が困るかなーと、ここ数ヶ月ぼんやり考えていました。誰でも使えるGUIがあるといいよね、と。
この数週間はすごく調子に乗っていて、「ちょっとC#かじってアプリをでっち上げよう!」と意気軒昂でしたが、うん、これ、そんな簡単なもんじゃないですね…SQLiteのドライバの挙動とか、C#の言語仕様とか、WPF(Windows Presentation Foundation、Visual C#でGUIアプリケーションを作るときの枠組みのひとつ)とかと1週間ちょい格闘した後、ふと我に返りました。
これ、完成しないんじゃね?
偉い人は言いました。「たぶん動くと思うからリリースしようぜ」と。
私の技術では動くところにすら到達出来ません。さっさと諦めて、いつも使っているPythonでWebアプリケーションにすることにしました。
こっちはプレゼン目的にでっち上げたこともありますので、すぐに作れます。
今、Jupyter Notebookでやっているデータの可視化や、このブログで書き殴ってきた様々なクエリ発行も、このアプリケーションに纏めていこうと考えています。
ちなみにGit Hubを使うのはこれが初めてで、ろくに使い方がわかってません。色々ヘンテコなところがあると思いますがご勘弁ください。
ツールの中身については…はい、ひどいシロモノです。色んな修正点が必要になると分かっています。
「なんてひどい!こんなの書き換えてやる!」と思った方は是非そうしてください。当然改変・再配布・利用フリーです。
持参薬の記録についてあれこれ
10月から持参薬の記録が必須になりました。
面倒極まりない仕様ですが、データを扱うときにも注意点が増えます。
というのも、この持参薬情報、
出来高実績点数や明細点数情報を保持したままなのです!
つまり、普通にEFファイルを集計すると、持参薬込の点数が出てしまいます。 (ひょっとすると、それが狙いでこういう仕様なのかも知れませんが…)
持参薬の有無や種別は行為明細区分情報の3桁目に記録されますので、こちらを利用すれば区分けは可能です。 例えば以下に、持参薬を除外した出来高点数集計の例を挙げます。
SELECT データ識別番号,入院年月日,SUM(出来高実績点数*行為回数) AS 出来高総点数 FROM ef1610 WHERE データ区分 <> 92 AND データ区分 <> 97 AND 行為明細区分情報 LIKE '__0_________' group by データ識別番号,入院年月日
該当のポイントはAND 行為明細区分情報 LIKE '__0_________'
です。
SQLなら大して難しいことではありませんが、面倒くさいですね。
再びのアプリケーション考察
データ分析をやっていると、やっぱり「アプリケーションで配布したい!」と思うときがあります。
(このブログで書いている諸々のSQL文も、まとめてアプリケーションにバンドルしてしまいたいのです)
最近真剣に選択肢を検討してみたので、結果をつらつら書くことにしました。
1. Pythonのままアプリケーション化する
ネットで検索すると色々な方法が見つかりますが、Pyinstallerを使うのが最も現実的でしょう。
他の方法、例えばPy2exeなんかは更新が止まっちゃってますし…
とはいえ、環境によってはPandasを含むアプリが上手くビルド出来なかったりします。
私が正にそうで、GitHubの開発中のビルドをぶっ込んだら走りましたが、うーん、安定はしてなさそうですね…
また、GUIをどうするか、という問題もあります。
PyQtが一番有名みたいですが、ライセンスがややこしそうです。別の選択肢として、Kivyが熱いみたいですが日本語の情報があまり出回っていません。
FlaskでWebアプリを作ってブラウザで使う、という手もありますけど…うーん…
2. Javascript + Node.js + Electronでアプリケーション化する
自分でもなぜこうしようと思ったのか分かりませんが、Node.jsで組んだウェブアプリをElectronというライブラリでデスクトップアプリに変換出来ます。
実際に使ってみようと、しばらくJavascriptとNode.jsの勉強をしてましたが…ましたが…うーん…csvを開くための方法が何パターンかあり、dataframeっぽいライブラリを使うにはbabelが必要で、うーん…
ただし、素の状態でJavascriptはPythonより速いです。numpy / PandasのようなC言語ライブラリを使えば話は変わってきますが。
ちょっと大きなデータの分析にも十分使えそう。今回は、学習時間が全く足りなかったということで…
3. 素直にC#を使う
初めからそうしろよ、と言われそうですがC#をいじってます。Visual Studioすごいべんりですね!(今更
別にJavaでもいいんですが、せっかくVisual Studioが無料化されたので。
Windowsをターゲットにするなら、最初っからこれで良かったですね…
ただ、グラフのプロット周りはあんまり期待できそうにありません。
(こちらはPythonが充実し過ぎているだけ、とも言えますが)