如何解决药物占有率(MPR)问题?

时间:2019-07-09 09:36:12

标签: clojure

我正在尝试解决药物占有率问题。

我尝试使用间隔,然后将它们与观察期进行比较。

(ns clara-rules.mpr-new
  (:require [clj-time.core :as t]
            [clj-time.format :as f]))

(defn observe [interval]
  (def start (map #(f/parse (f/formatter "dd MM yyyy") (% :start_)) interval))
  (def end (map #(f/parse (f/formatter "dd MM yyyy") (% :end_)) interval))

  )
(observe '({: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"}))


(defn calc[a b]
(def start_date (f/parse (f/formatter "dd MM yyyy") a)
  )

  (def end_date (f/parse (f/formatter "dd MM yyyy")b)
      )

  (def observation_period(t/in-days(t/interval start_date end_date)))
  (println observation_period)
  )
(calc "01 02 2012" "01 12 2012")

(defn mpr_ratio[]

  (def overlp (map #(t/overlap (t/interval start_date end_date) (t/interval %1 %2))start end))

  (def x (map #(t/in-days %)overlp))
  (println x)
  (def ratio (reduce +(map #(float(*(/ % observation_period)100))x)))
  (println ratio)
  )
(mpr_ratio)

我希望所有间隔和观察期的计算比率。

2 个答案:

答案 0 :(得分:2)

这就是日期间隔功能的样子:

(defn process []
  (let [from ["20 01 2012"
              "20 03 2012"
              "20 06 2012"
              "20 08 2012"]
        to ["20 02 2012"
            "20 05 2012"
            "20 07 2012"
            "20 09 2012"]
        get-date (partial f/parse (f/formatter "dd MM yyyy"))
        days (map #(t/in-days (t/interval (get-date %1) (get-date %2)))
                  from to)]
    days))

user> (process)
;;=> (31 61 30 31)

不过,我建议您阅读一些有关Clojure的介绍

答案 1 :(得分:1)

一些建议:

  1. 使用具有返回值的函数而不是依靠副作用(函数内部的printlndef)来获取结果
  2. 仅将def用于顶级变量,将let用于任何临时变量 在函数内部
  3. 创建一些单一用途的函数(例如,用于解析日期的函数;用于将观测值列表转换为日期的函数),然后使用这些函数来构成您的解决方案
  4. 使用线程宏(例如-> ->>)来提高可读性

可能的解决方案:

(def fmt
  "default date formatter"
  (f/formatter "dd MM yyyy"))

(def ->date
  "utility function to convert string to date"
  (partial f/parse fmt))

(->date "01 02 2012")
;; => #object[org.joda.time.DateTime 0x6e880ccd "2012-02-01T00:00:00.000Z"]

(defn ->observations
  [intervals]
  (->> intervals
       (map (fn [{:keys [start_ end_]}]
              {:start (->date start_)
               :end   (->date end_)}))))

(->observations '({:start_ "20 01 2012" :end_ "20 02 2012"}
                  {:start_ "20 02 2012" :end_ "20 03 2012"}))
;; => ({:start #object[org.joda.time.DateTime 0x4eb450bd "2012-01-20T00:00:00.000Z"], :end #object[org.joda.time.DateTime 0x558bd20f "2012-02-20T00:00:00.000Z"]} {:start #object[org.joda.time.DateTime 0x4009d145 "2012-02-20T00:00:00.000Z"], :end #object[org.joda.time.DateTime 0x42e32d6 "2012-03-20T00:00:00.000Z"]})

(defn mpr_ratio
  [start_date end_date intervals]
  (let [intrvrl   (t/interval start_date end_date)
        obsrv-prd (t/in-days intrvrl)]
    (->> (map t/interval (map :start intervals) (map :end intervals))
         (map (partial t/overlap intrvrl))
         (map t/in-days)
         (map #(-> %
                   (/ obsrv-prd)
                   (* 100.0)))
         (reduce +))))

(mpr_ratio (->date "01 02 2012")
           (->date "01 12 2012")
           (->observations '({: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"})))
;; => 35.526315789473685

更新-PDC实用程序功能

(defn covered [state interval]
  (if (some #(t/overlaps? interval %) state)
    (->> state
         (map #(if (t/overlaps? interval %)
                 (t/interval (t/min-date (t/start %) (t/start interval))
                             (t/max-date (t/end %) (t/end interval)))
                 %))
         (into (empty state)))
    (conj state interval)))

(covered #{} (t/interval (->date "01 02 2012") (->date "05 02 2012")))
;; => #{#object[org.joda.time.Interval 0x30addc0b "2012-02-01T00:00:00.000Z/2012-02-05T00:00:00.000Z"]}
(covered *1 (t/interval (->date "04 02 2012") (->date "07 02 2012")))
;; => #{#object[org.joda.time.Interval 0x7f8893c1 "2012-02-01T00:00:00.000Z/2012-02-07T00:00:00.000Z"]}
(covered *1 (t/interval (->date "02 03 2012") (->date "07 03 2012")))
;; => #{#object[org.joda.time.Interval 0x7f8893c1 "2012-02-01T00:00:00.000Z/2012-02-07T00:00:00.000Z"] #object[org.joda.time.Interval 0x67adc8d1 "2012-03-02T00:00:00.000Z/2012-03-07T00:00:00.000Z"]}
(reduce + (map (comp inc t/in-days) *1))
;; => 13

完整的pdc功能:(请注意,只需添加一行)

(defn pdc_ratio
  [start_date end_date intervals]
  (let [intrvrl   (t/interval start_date end_date)
        obsrv-prd (t/in-days intrvrl)]
    (->> (map t/interval (map :start intervals) (map :end intervals))
         (map (partial t/overlap intrvrl))
         ;; get covered days only
         (reduce covered #{})
         (map t/in-days)
         (map #(-> %
                   (/ obsrv-prd)
                   (* 100.0)))
         (reduce +))))