如何解决药物持有率(MPR)计算问题?附代码实现疑问
解决药物持有率(MPR)计算的Clojure实现问题
我明白你现在在尝试用Clojure计算药物持有率(MPR),通过对比用药区间和观察期来得到比率。先看看你写的代码里几个需要调整的地方,然后咱们一起重构出更可靠的实现:
原代码的主要问题
- 全局变量滥用:你在函数内部用
def定义start、end、start_date这些变量,这会创建全局状态,不仅容易导致数据混乱,也不符合Clojure函数式编程的理念,应该用let来创建局部绑定。 - 函数耦合性高:
mpr_ratio完全依赖全局的start、end、observation_period,没法灵活处理不同的输入数据。 - 边界情况未处理:如果观察期天数为零,或者某个用药区间和观察期完全不重叠,代码会出现错误。
修正后的完整实现
咱们把代码拆成单一职责的小函数,用局部绑定替代全局变量,同时处理边界情况:
(ns clara-rules.mpr-new (:require [clj-time.core :as t] [clj-time.format :as f])) ;; 定义全局日期格式化器,避免重复创建 (def date-formatter (f/formatter "dd MM yyyy")) ;; 解析用药区间:把字符串日期转换成clj-time的日期对象 (defn parse-intervals [intervals] (map (fn [{:keys [start_ end_]}] {:start (f/parse date-formatter start_) :end (f/parse date-formatter end_)}) intervals)) ;; 计算观察期的总天数 (defn observation-period-days [start-str end-str] (let [start-date (f/parse date-formatter start-str) end-date (f/parse date-formatter end-str)] (t/in-days (t/interval start-date end-date)))) ;; 核心MPR计算函数:返回每个区间的比率和总比率 (defn calculate-mpr [parsed-intervals obs-start-str obs-end-str] (let [obs-start (f/parse date-formatter obs-start-str) obs-end (f/parse date-formatter obs-end-str) obs-interval (t/interval obs-start obs-end) obs-days (t/in-days obs-interval)] (if (zero? obs-days) (throw (IllegalArgumentException. "观察期天数不能为零,请检查日期输入")) (let [;; 计算每个用药区间和观察期的重叠部分 interval-overlaps (map (fn [{:keys [start end]}] (t/overlap obs-interval (t/interval start end))) parsed-intervals) ;; 处理无重叠的情况,默认0天 overlap-days (map #(if % (t/in-days %) 0) interval-overlaps) ;; 计算每个区间的MPR比率(百分比) individual-ratios (map #(float (* (/ % obs-days) 100)) overlap-days) ;; 计算总MPR比率 total-ratio (reduce + individual-ratios)] {:individual-ratios individual-ratios :total-ratio total-ratio})))) ;; ------------------- 使用示例 ------------------- (def sample-intervals '({:start_ "20 01 2012" :end_ "20 02 2012"} {:start_ "20 02 2012" :end_ "20 03 2012"} {:start_ "20 04 2012" :end_ "20 05 2012"} {:start_ "20 06 2012" :end_ "20 07 2012"})) ;; 解析示例区间 (def parsed-sample (parse-intervals sample-intervals)) ;; 计算MPR(观察期:2012-02-01 到 2012-12-01) (def mpr-result (calculate-mpr parsed-sample "01 02 2012" "01 12 2012")) ;; 输出结果 (println "每个用药区间的MPR比率(百分比):" (:individual-ratios mpr-result)) (println "总MPR比率(百分比):" (:total-ratio mpr-result))
代码说明
- 局部绑定替代全局变量:所有临时变量都用
let定义在函数内部,不会污染全局命名空间,数据更安全。 - 单一职责函数:每个函数只做一件事,比如
parse-intervals只负责解析日期,calculate-mpr专注于核心计算,代码更易维护和调试。 - 边界处理:如果观察期天数为零,会抛出明确的异常;如果用药区间和观察期无重叠,自动按0天计算比率,避免
nil错误。 - 清晰的结果返回:返回一个包含
individual-ratios(每个区间的比率)和total-ratio(总比率)的map,方便你后续使用这些结果。
运行这段代码后,你就能得到每个用药区间与观察期的MPR比率,以及所有区间的总比率啦。
内容的提问来源于stack exchange,提问作者CoDInG brO
相关产品推荐
相关产品推荐

