DPCチェッカー0.11 認知症ケア加算のチェック機能を追加
例によってこちらです。
今回は単なるクエリの追加だけですが、SQLiteの仕様について面白いことも分かったので、いずれ別記事で書きます。
また、今後の方針についてですが・・・
今後の方針
- やっぱりexeで走るアプリケーションにしたい
- 中身のコードがひどいのでリファクタリングしたい
- もうちょいマシな統計機能をつけたい
などとなっております。
exeについては、Pyinstallerの開発版を使えば可能だと分かりました。
ええ、開発版です。公式の最新版、3.2.1だとバグってビルド出来ないことは確認してます。
- このままビルドして配布しても、この後継続的に更新出来るか分からない
- 成功したビルドが400MB近くある
などの問題があり、もんにょりしてます。
これはPyinstallerの問題というよりは、Pandas/numpyとPyinstallerの相性問題でして、うーん、ちょっと先行きが分からないですね。
(ちなみに書いておくと、Pyinstallerは標準ライブラリで組まれたコードをアプリ化する限り、殆ど問題を起こしません)
「改訂新版JavaScript本格入門」を読みました
今書いているアプリケーションでは、ブラウザを使ったデータの可視化をやってます。
残念ながらその部分はJavaScriptに頼らざるを得ず、コピペと当てずっぽうではコードが動かないので、本を買いました。
「改訂新版JavaScript本格入門」は、痒いところに手の届く参考書です。
実は「JavaScript : The Good Parts」も読んだんですが、流石にもう2017年です。今なら「改訂新版JavaScript本格入門」がオススメですね。
名著「The Good Parts」よりこちらを勧めるのはなんで?
JavaScriptの言語仕様が変わりすぎだからです。
とりわけECMAScript2015での追加は凄まじく、「本格入門」でも章の半分が「今までの話」でもう半分が「これからの話」に分かれてるとかザラでした。Python界隈が未だに 2.x系と3.x系で議論してるのが、微笑ましくなるような強烈さです。
Wikipediaで追加事項を見てみましょう。
クラス、モジュール、イテレータ、for/ofループ、Pythonスタイルのジェネレータ、アロー関数、2進数および8進数の整数リテラル、Map、Set、WeekMap、WeekSet、プロキシ、テンプレート文字列、let、const、型付き配列、デフォルト引数、Symbol、Promise、分割代入、可変長引数
さらっと「クラス、モジュール、イテレータ」とか出てきてますね。
今までどうしてたんでしょうか・・・と思ったら、プロトタイプチェーンなるものが使われていたそうです。
また、アロー関数は冗長なfunction () { ... }
記法を簡略化したもので、() => {....}
(場合により{}省略可)というモダンな何だかScalaっぽい記法が使えます。
constは変更不可能な変数(というか定数)定義で、やっぱりScalaのvalっぽい関数型言語で流行のイミュータブルな奴ですね。
私のような、ECMA2015以降にJavaScriptを触り始めた、完全な門外漢でも驚く変わりようです。
(一応書いておくと、クラスは今までのオブジェクト仕様のシンタックスシュガーだそうで、根本から入れ替えたというわけでもなさそうですが・・・)
正直、以前はJavaScriptに手を出すつもりはありませんでしたが、ブラウザに手を出せば絶対に逃げられない言語です。何かの機会に学ばざる得なくなるので、解説本をざっと読むのはいいと思いました。
(自分が公開しているDPCチェッカーの、あまりに酷いJavaScript部分はあとで書き直します・・・)
行値式を使った条件指定について(Postgres SQL前提)
保険算定というのは奇々怪々です。
あまりにも制度が複雑になりすぎて、「○○を行った患者さんで、××は算定してなくて、でも△△を算定してる人が知りたい」みたいな問題が割と出てきます。
一つ一つの条件は単純ですが、重なってくると面倒ですね。
さて、入院データを元に抽出をかけるとすると、「一人」ではなく「一入院」を単位とするのが一般的です。
つまり、先ほどのめんどくさいパターンマッチは、「その人」ではなく「その入院」に対してかけないといけません。
具体的に言えば、データ識別番号
だけでは駄目で、入院年月日
も使って探す必要があります。
(DPCデータの分析では、まずデータ識別番号と入院年月日を組み合わせてキーを作るのが基本です)
では実際にやってみましょう。こんな感じでしょうか。
select * from ef1612 Where 診療明細名称 LIKE '%探しているもの%' AND (データ識別番号,入院年月日) NOT IN (select distinct データ識別番号,入院年月日 from efile Where 診療明細名称 LIKE '%算定してない条件%') AND (データ識別番号,入院年月日) IN (select distinct データ識別番号,入院年月日 from efile Where 診療明細名称 LIKE '%算定してる条件%') --以下延々と続く
さて、上記のSQLは一体何をしているのでしょう。
AND (データ識別番号,入院年月日) IN (select distinct データ識別番号,入院年月日 from efile Where 診療明細名称 LIKE '%なんとか%')
SQLでは、INを使って一定の条件に当てはまるデータを抽出出来ます。イメージとしては
123 in [123,456,789]
のような処理を考えてみましょう。上の例では123
は右側のリストの先頭にあります。
同じように上記の例では、データ識別番号,入院年月日
のペアが存在するかどうかを探しているのです。
IN
の横で唐突にSELECT文が走っていますが、よく見ると'データ識別番号,入院年月日'のペアを引っ張るようになっています。
逆に特定条件を満たしていないものを探したければ、NOT IN
を使えばいいだけです。
この例で分かるとおり、ブロックを並び続けることで、いくらでも条件を追加出来ます。
ただし、上記の()
を使ってペア(もしくはそれ以上の複数条件)を使う記法は行値式といって、Postgresなど一部SQLにしか実装されていません。
(代表的なところでは、MicrosoftのSQL Serverでは未対応です)
その場合はEXISTSなどを使って書き換える必要があります。
非常に便利で、自分は実務で連発してますが、案外使わないもんなんでしょうか・・・?
DPC疾患の月別推移を可視化する(修正版)
前回はタイトル通り、DPC疾患の月別推移を可視化する関数を書きました。
あれは実行するとデータを作り、同時にグラフを描画するというひどい代物で、流石に反省しましたのでクラスに書き換えてみました。
何気にこのブログでクラスを書くのは初めてですね。
今までいかにサボっていたかよく分かります・・・
class diff_dpc: '''前月との疾患別比較を出す。funcはmean,sum,count辺りがいいが、 groupbyで使えるなら何でもよい kaはオプションだが、あった方がグラフが見やすい''' def __init__(self,df,ka=None,func='sum'): self.df = df self.ka = ka self.func = func if self.ka: self.df = self.df[self.df['診療科区分'] == self.ka] else: pass self.df['MDC6'] = [x[0:6] for x in self.df['分類番号']] self.result = self.df.groupby(['month','MDC6']).agg(self.func) self.result.reset_index(inplace=True) def plot(self): ax = sns.barplot(x='MDC6',y='dpc総点数',hue='month',data=self.result) for item in ax.get_xticklabels(): item.set_rotation(90) plt.show() def getdata(self): return self.result
使い方は
test = diff_dpc(df,ka=110,func='count')
のようにしてやります。すると二つのメソッドを持ったオブジェクトが出来ますので、
test.plot()
でグラフを描画、'test.getdata()'でデータの取り出しが出来ます。
(別にインスタンス変数を指定しても同じ事なので、'test.result'としても問題ありません)
DPC疾患の月別推移を可視化する
今回はDPC入院料の分析のお話です。
DPC入院料の推移を見ると、時折奇妙な動きをすることがあります。特定の科の数字が跳ね上がったり、下がったりです。
もちろん中身をチェックすることになりますが、毎回集計して目で見るのは面倒ですね。自動化しましょう。
まず、元のデータとしてこんなものを用意します。
data = psql.read_sql("select to_char(実施年月日,'YYYYMM') AS month,データ識別番号,実施年月日,診療科区分,分類番号, \ sum(行為点数*行為回数) AS DPC総点数 \ from dtable \ Where データ区分 = 93 \ group by month,データ識別番号,実施年月日,診療科区分,分類番号",connection)
これで、診療月/診療科区分/分類番号を含むデータが得られました。
さて、次に出すのは分類別の集計です。DPC分類を使うとデータが細かくなりすぎますので、MDC6を使うことにします。
(分類番号の頭6桁を切り出すだけです)
点数合計の推移が見たいときもあれば、延べ件数が見たいとき、平均が見たいときなどもあるでしょう。
グラフに出来るといいですね。
深く考えずに全部突っ込んでみます。
def diff_dpc(df,ka=None,func='sum'): '''月別・MDC6別に集計したDataFrameを返す。funcはmean,sum,count辺りが良いが、 groupbyで使えるなら何でもいい。 同時に比較結果をグラフにして表示する。 kaはオプションだが、無いと項目数が多すぎてグラフが見づらい''' if ka: df = df[df['診療科区分'] == ka] else: pass df['MDC6'] = [x[0:6] for x in df['分類番号']] result = df.groupby(['month','MDC6']).agg(func) result.reset_index(inplace=True) ax = sns.barplot(x='MDC6',y='dpc総点数',hue='month',data=result) for item in ax.get_xticklabels(): item.set_rotation(90) plt.show() return result
実際には
diff_dpc(data,ka=110,func='count')
のようにして使います。
グラフの描画は完全に副作用ですし、引数で指定するかclassに書き換えて独立メソッドにした方がいい気もしますね…
認知症ケア加算の算定ミスをチェックする
明けましておめでとうございます。
つい数日前のエントリで、今年はSQL紹介だけの単調なエントリはやらないぞ!と書いておいてアレですが、算定ミスチェックのSQLでございます。
認知症ケア加算は、「入院後14日以前か、15日以降か」で算定する点数が変わります。
残念ながら、手入力をしていると、わりかしポコポコ算定ミスが出てきます。そこで、簡単なチェックを作ってみました。
SELECT データ識別番号,入院年月日,実施年月日,診療明細名称 FROM EFILE WHERE 診療明細名称 LIKE '%認知症ケア%14日%' AND 行為明細番号 = 0 AND 実施年月日 - 入院年月日 + 1 > 14 ORDER BY データ識別番号
認知症ケア加算には1と2がありますが、どちらを算定する病院でも使えます。
ここでは、入院15日目以降にも14日以内のコードを算定しているものを拾っています。
新年早々こんなんで申し訳ありませんが、今年もよろしくお願いいたします。
2016年の終わりに
このブログを始めたのが今年の1月でしたので、年が明ければ一周年となります。
お読み頂いた皆さんには、お付き合い頂き有り難うございました。
来年はもう少しマシな内容になると思います・・・うーん、なる、はず・・・なるといいな・・・
2016年のまとめ
今年はずっとPostgresとPandasの話ばっかり書いていました。
個人的には2015年からやっていましたが、今年はPython本がたっぷり出版されて、いよいよ「データ分析=Python」という空気が広まった感があります。
また、Rについてもたくさん本が出ましたから、そういう年だったのでしょう。
個人的な体験からすると、Pythonはプログラマではない人のための第一言語です。
更に言えば、日々の仕事を楽にするために、ちょっとしたハックが必要な人に最適です。シェルスクリプトより汎用性があり、習得が楽で、しかも最高のデータ操作ライブラリを持っています。こんな言語は他に見当たりません。
今年仕事をしながら感じたのは、そろそろ事務仕事にもコードが必要な頃合いだ、ということです。別にプロのプログラマを必要としているわけじゃありません・・・たぶん、10行か20行、ぱぱっとでっち上げるだけで、随分助かるという仕事は多いんじゃないでしょうか。
2017年の展望
出来れば来年は、もう少し応用的な話を書けるようになりたいものです。
Pythonを使った統計分析や、機械学習は、私自身も実務での適用例がありません。
基礎の勉強はそこそこやっていたので、来年はいよいよ実践かなあ・・・
また、ブログの趣旨からは外れますが、余談を少し。
ウェブは世の中全てにやって来ます。「ウェブ」という言葉で意味するのは、HTML/CSS/JavaScriptです。私の読みが間違いでなければ、恐らく新規のデスクトップアプリケーションの多くがElectronベースに、すなわちNode.js上に構築されるようになるでしょう。
自分でもElectronでプロトタイプを組んだのですが、思った以上に簡単にアプリケーションが出来てしまうので驚きました。
ウェブアプリケーションをそのままデスクトップに持ってこれる、というのは本当に大きいです。
ということで、来年は
- Pythonを使った統計分析
- Pythonを使った(簡単な)機械学習
- JavaScriptを使ったデスクトップアプリ作成
あたりにチャレンジしようかなあ、と思います。
それでは皆様、よいお年を。