我正在尝试解决药物占有率问题。
我尝试使用间隔,然后将它们与观察期进行比较。
(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)
我希望所有间隔和观察期的计算比率。
答案 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)
一些建议:
println
和def
)来获取结果def
用于顶级变量,将let
用于任何临时变量
在函数内部->
->>
)来提高可读性可能的解决方案:
(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 +))))