Skip to content

Commit df1bb35

Browse files
committed
first
0 parents  commit df1bb35

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2274
-0
lines changed

.editorconfig

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
trim_trailing_whitespace = true
7+
8+
[*.rb]
9+
indent_style = space
10+
indent_size = 2
11+
12+
[*.{js,jsx,css,less,html}]
13+
indent_style = space
14+
indent_size = 2

.gitignore

Whitespace-only changes.

.ruby-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.0.2

Dockerfile

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM ruby:3.0.2-buster
2+
3+
RUN apt-get update && \
4+
apt-get install -y --no-install-recommends \
5+
less
6+
7+
ENV BUNDLE_JOBS=4 \
8+
LANG=ja_JP.UTF-8 \
9+
PAGER=less \
10+
TZ=Asia/Tokyo
11+
12+
WORKDIR /app

Gemfile

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
4+
5+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6+
7+
gem "mysql2"
8+
gem "rubyXL"
9+
gem "ridgepole"
10+
gem "sequel"

Gemfile.lock

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
activemodel (6.1.4.1)
5+
activesupport (= 6.1.4.1)
6+
activerecord (6.1.4.1)
7+
activemodel (= 6.1.4.1)
8+
activesupport (= 6.1.4.1)
9+
activesupport (6.1.4.1)
10+
concurrent-ruby (~> 1.0, >= 1.0.2)
11+
i18n (>= 1.6, < 2)
12+
minitest (>= 5.1)
13+
tzinfo (~> 2.0)
14+
zeitwerk (~> 2.3)
15+
concurrent-ruby (1.1.9)
16+
diffy (3.4.0)
17+
i18n (1.8.10)
18+
concurrent-ruby (~> 1.0)
19+
minitest (5.14.4)
20+
mysql2 (0.5.3)
21+
nokogiri (1.12.4-x86_64-darwin)
22+
racc (~> 1.4)
23+
nokogiri (1.12.4-x86_64-linux)
24+
racc (~> 1.4)
25+
racc (1.5.2)
26+
ridgepole (0.9.6)
27+
activerecord (>= 5.1, < 6.2)
28+
diffy
29+
rubyXL (3.4.18)
30+
nokogiri (>= 1.10.8)
31+
rubyzip (>= 1.3.0)
32+
rubyzip (2.3.2)
33+
sequel (5.48.0)
34+
tzinfo (2.0.4)
35+
concurrent-ruby (~> 1.0)
36+
zeitwerk (2.4.2)
37+
38+
PLATFORMS
39+
x86_64-darwin-20
40+
x86_64-linux
41+
42+
DEPENDENCIES
43+
mysql2
44+
ridgepole
45+
rubyXL
46+
sequel
47+
48+
BUNDLED WITH
49+
2.2.26

README.md

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
[NDBオープンデータ](https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000177182.html) をさわるためのリポジトリです。
2+
3+
# 手順
4+
5+
## DBを立ち上げて、NDBのデータをDBにインポートする手順
6+
7+
```sh
8+
9+
# 準備
10+
# dockerをインストールしておく
11+
12+
# DB起動
13+
docker compose up
14+
15+
# NDBのデータをインポートする
16+
cd scripts
17+
docker compose run --rm ruby bundle exec ridgepole -c 'mysql2://root:password@mariadb:3306/ndb_sandbox' -f ./db/Schemafile --apply
18+
docker compose run --rm ruby bundle exec ridgepole -c ./db/config.yml -f ./db/Schemafile --apply
19+
docker compose run --rm ruby bundle exec ruby app/import_csv.rb
20+
21+
# その後
22+
# phpmyadminとかredashとかで接続してなにかをする
23+
24+
```
25+
26+
## csvファイルを再作成する手順
27+
28+
```sh
29+
30+
cd scripts
31+
docker compose run --rm ruby bundle exec ruby app/to_csv.rb
32+
33+
# sources/以下にcsvファイルができる
34+
# エラー出た場合は想定してるファイルフォーマットじゃない可能性があるのでto_csv.rbを修正すること
35+
36+
```
37+
38+
# sources以下について
39+
40+
## 第6回NDBオープンデータ
41+
42+
### 歯科傷病
43+
44+
| filenmae | desc |
45+
| --- | --- |
46+
| 000821581.xlsx | 性年齢別 傷病件数 |
47+
48+
### 歯科診療行為
49+
50+
| filenmae | desc |
51+
| --- | --- |
52+
| 000821521.xlsx | A基本診療料 初再診料_性年齢別算定回数 |
53+
| 000821529.xlsx | B医学管理等 性年齢別算定回数 |
54+
| 000821532.xlsx | C在宅医療 性年齢別算定回数 |
55+
| 000821535.xlsx | D検査 性年齢別算定回数 |
56+
| 000821539.xlsx | E画像診断 性年齢別算定回数 |
57+
| 000821542.xlsx | F投薬 性年齢別算定回数 |
58+
| 000821545.xlsx | G注射 性年齢別算定回数 |
59+
| 000821549.xlsx | Hリハビリテーション 性年齢別算定回数/単位数 |
60+
| 000821552.xlsx | I処置 性年齢別算定回数 |
61+
| 000821555.xlsx | J手術 性年齢別算定回数 |
62+
| 000821558.xlsx | J輸血料 性年齢別算定回数 |
63+
| 000821564.xlsx | K麻酔 性年齢別算定回数 |
64+
| 000821567.xlsx | L放射線治療 性年齢別算定回数 |
65+
| 000821570.xlsx | M歯冠修復及び欠損補綴 性年齢別算定回数 |
66+
| 000821573.xlsx | N歯科矯正 性年齢別算定回数 |
67+
| 000821576.xlsx | O病理診断 性年齢別算定回数 |

app/import_csv.rb

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
require "csv"
2+
require "sequel"
3+
require "yaml"
4+
5+
class ImportCsv
6+
BASE_PATH = "."
7+
MAX_AGE = 999
8+
AGE_STEP = 5
9+
10+
def initialize
11+
config = YAML.load_file("#{BASE_PATH}/db/config.yml")
12+
@db = Sequel.connect(config)
13+
end
14+
15+
def perform
16+
import_disease
17+
import_practice
18+
ensure
19+
@db.disconnect # いらんか
20+
end
21+
22+
def import_disease
23+
puts "歯科傷病のインポート開始"
24+
dental_disease_counts = @db[:dental_disease_counts]
25+
source = "#{BASE_PATH}/sources/第6回NDBオープンデータ/歯科傷病/000821581.csv"
26+
puts "#{source}を読み込み"
27+
CSV.foreach(source, encoding: "UTF-8:UTF-8") do |row|
28+
# 総計
29+
dental_disease_counts.insert(
30+
disease_group: row[0],
31+
code: row[1],
32+
name: row[2],
33+
sex: nil,
34+
age_upper: nil,
35+
age_lower: nil,
36+
count: normalize_count(row[3]),
37+
is_total: true
38+
)
39+
# 男性
40+
row[4..22].each_with_index do |c, i|
41+
range = age_range(i)
42+
rec = {
43+
disease_group: row[0],
44+
code: row[1],
45+
name: row[2],
46+
sex: "male",
47+
age_upper: range[:upper],
48+
age_lower: range[:lower],
49+
count: normalize_count(c),
50+
is_total: false
51+
}
52+
dental_disease_counts.insert(rec)
53+
end
54+
55+
# 女性
56+
row[23..41].each_with_index do |c, i|
57+
range = age_range(i)
58+
rec = {
59+
disease_group: row[0],
60+
code: row[1],
61+
name: row[2],
62+
sex: "female",
63+
age_upper: range[:upper],
64+
age_lower: range[:lower],
65+
count: normalize_count(c),
66+
is_total: false
67+
}
68+
dental_disease_counts.insert(rec)
69+
end
70+
end
71+
puts "歯科傷病のインポート完了"
72+
end
73+
74+
def import_practice
75+
puts "歯科診療行為のインポート開始"
76+
dir = "#{BASE_PATH}/sources/第6回NDBオープンデータ/歯科診療行為"
77+
Dir.glob("#{dir}/*.csv").each do |file|
78+
import_practice_file(file)
79+
end
80+
puts "歯科診療行為のインポート完了"
81+
end
82+
83+
def import_practice_file(source)
84+
dental_practice_counts = @db[:dental_practice_counts]
85+
puts "#{source}を読み込み"
86+
CSV.foreach(source, encoding: "UTF-8:UTF-8") do |row|
87+
# 総計
88+
dental_practice_counts.insert(
89+
category_code: row[0],
90+
classification_name: row[1],
91+
code: row[2],
92+
name: row[3],
93+
score: normalize_count(row[4]),
94+
sex: nil,
95+
age_upper: nil,
96+
age_lower: nil,
97+
count: normalize_count(row[5]),
98+
is_total: true
99+
)
100+
# 男性
101+
row[6..24].each_with_index do |c, i|
102+
range = age_range(i)
103+
rec = {
104+
category_code: row[0],
105+
classification_name: row[1],
106+
code: row[2],
107+
name: row[3],
108+
score: normalize_count(row[4]),
109+
sex: "male",
110+
age_upper: range[:upper],
111+
age_lower: range[:lower],
112+
count: normalize_count(c),
113+
is_total: false
114+
}
115+
dental_practice_counts.insert(rec)
116+
end
117+
118+
# 女性
119+
row[25..43].each_with_index do |c, i|
120+
range = age_range(i)
121+
rec = {
122+
category_code: row[0],
123+
classification_name: row[1],
124+
code: row[2],
125+
name: row[3],
126+
score: normalize_count(row[4]),
127+
sex: "female",
128+
age_upper: range[:upper],
129+
age_lower: range[:lower],
130+
count: normalize_count(c),
131+
is_total: false
132+
}
133+
dental_practice_counts.insert(rec)
134+
end
135+
end
136+
end
137+
138+
def normalize_count(count)
139+
count == "-" ? 0 : count.to_i
140+
end
141+
142+
# 下記のような年代の上限下限を返す
143+
# 0~4歳,5~ 9歳,10~14歳,15~19歳,20~24歳,25~29歳,30~34歳,35~39歳,40~44歳,45~49歳,50~54歳,55~59歳,60~64歳,65~69歳,70~74歳,75~79歳,80~84歳,85~89歳,90歳以上
144+
def age_range(index)
145+
lower = index * AGE_STEP
146+
{
147+
upper: index == 18 ? MAX_AGE : lower + AGE_STEP - 1,
148+
lower: lower
149+
}
150+
end
151+
end
152+
153+
ImportCsv.new.perform

0 commit comments

Comments
 (0)