(ns eau-nccn "Script to explore how different patient groups are classified according to the 2025 EAU Guidelines for Prostate Cancer and the NCCN. It starts by creating a list of all the permutations of the relevant markers, then applying the different classifications to each permutation. Finally, we calculate the % of each classification and the frequency of each EAU<>NCCN combination. The Sankey diagram can be accessed via this public link: https://sankeymatic.com/build/?i=PTAEFEDsBcFMCdQDEA2B7A7gZ1AI1tBrLJKAHJoAmsWANKCgJYDWso0AFo1gFwBQIUEOHCAymgCu8AMZsA2gEEAsgHkAqmQAqAXVCaAhvADmBPnzIBhC2VAAZTKHjdmoOQBZd4BWrsOnWZnMrGyR9ADdJeH1cFHkAVk9vZHDI6Nig61A1SAAzFKk0%2BQBGAA5En2y8iIKY2AybAAlGIw5HZ1cigGYAJnLQJpa2gLNLTNDqqNqOvoHW%2D0DRm0r8ydjXAE4%2B8dTa%2BqzclcKOopnmueczM0EATUlQaX1SLAJQfXIqWAByHGk0dHh6ExWOwuLwBGAeAAhCSUEzQUAAYgADHEAOzgkSY4QAOlxaEQb1%2B%2D1AOXxr1AWEYkCMa1QmH4gmhsJechOoBUnAQ5FgsiwlOgjBoiIAbEjhVcwAAiOQAKm0ktAAFtYI8cJK1M9XpAAJ6vRWSGAMWA5eFoMIISUMsBMuGuOWgUThKlGLASrKazn3NAweB%2DHD4dAYdhoe4SLDQNCKxgALzqgm1kVAlEY%2BiMUUV31eAAcsyqopBZLjsXxKbHQEHRUi%2BEJWpW%2BIrDEYqQxQEVutXHK320J4aUO7hQN0q7gjF7iQicpOpx3oPmsFnDCR4WQ%2BJAPuWux3WnEq0J5%2DppM7QKi4v38dRELuQbBla8O0SyQiSs%2BXx20AvD9BdUU%2BDlA6H4DCfRoCkNgkWxU8hCpDgEEYaAcl9RVQEkaBKWoABaKl7z%2BR91jw%2DC3w%2DODdXAtxTxQfQEwkU14AvV5qMjYDGGkDsACswwFHIEycJtIBwFchHY8NGC4khKH4jt4Fgc14GeNN9CzVoBNeaBoAPLgC0jLNYjgcMQ0gPMaGgPgKIDH4cMQZEkWs6yt0YahyDslomBaeFwJPDtSRgPJZApVV0OeJwcg7JgDP3Q9qVAcDu0cWAKIFc1SzYIoiivBsjEgETv1s0y4sgfRbwU3NDBwa4OyS1txSEIgznhNwcuiOKgJQCQ2CKvNSs8iQUBQLMpMPSlvVAMqhCzNB%2BUYIaA0wDsatc0B6qrXLevGuDJtIfQGP0FzSCvLBpBgwqGM8xhZPhfBSSk%2DspP0ZgxqpeFOj4ZrWpJfEG3hT5aGxT4Oz641GAAD1AT5fr3CRJyBkHfs5ZU0EnZ54TedZ%2Byi%2B9QCeoRKAx%2BsCDeZUYHWrBHlYbUPuYxyhCYYTFVwbbHl5YagA ") (def perms (for [psa [9 15 21] biopsy [1 2] isup [1 2 3 4 5] t-stage [1 2 3 4 5 6]] {:psa psa :biopsy biopsy :isup isup :t-stage t-stage})) (defn t " Map t-stage to an integer for easier math. " [k] (let [t-stages [:t1 :t2a :t2b :t2c :t3 :t4] t-mapping (zipmap t-stages [1 2 3 4 5 6])] (if (contains? t-mapping k) (k t-mapping) (throw (ex-info (str t " is not a valid t-stage! Valid stages " t-stages) {:k k :t-mapping t-mapping}))))) (defn eau-low [{:keys [psa isup t-stage]}] (and (= isup 1) (< psa 10) (<= t-stage (t :t2a)))) (defn eau-favorable [{:keys [psa isup t-stage]}] (or (and (= isup 2) (< psa 10) (<= t-stage (t :t2b))) (and (= isup 1) (<= 10 psa 20) (<= t-stage (t :t2b))) (and (= isup 1) (< psa 10) (= t-stage (t :t2b))))) (defn eau-unfavorable [{:keys [psa isup t-stage]}] (or (and (= isup 2) (<= 10 psa 20) (<= t-stage (t :t2b))) (and (= isup 3) (<= t-stage (t :t2b))))) (defn eau-high [{:keys [psa isup t-stage]}] (or (> isup 3) (> psa 20) (>= t-stage (t :t2c)))) (defn eau [m] (cond (eau-high m) :high-risk (eau-low m) :low-risk (eau-favorable m) :favorable (eau-unfavorable m) :unfavorable :else :uncategorized)) (def eau-freqs (->> perms (map #(assoc % :eau (eau %))) (map :eau) (frequencies))) (defn add-percent [perms freqs] (reduce (fn [p c] (update p c (fn [v] [v (str (int (* (/ v (count perms)) 100)) "%")]))) freqs (keys freqs))) ;; ---------------------------------------------------------------------------- (defn nccn-low [{:keys [psa isup t-stage]}] (and (= isup 1) (< psa 10) (<= t-stage (t :t2a)))) (def nccn-intermediate-factors [(fn [{:keys [isup]}] (<= 2 isup 3)) (fn [{:keys [psa]}] (<= 10 psa 20)) (fn [{:keys [t-stage]}] (<= (t :t2b) t-stage (t :t2c)))]) (defn nccn-n-intermediate-risk-factors [perm] (->> nccn-intermediate-factors (map #(% perm)) (filter true?) (count))) (defn nccn-favorable [{:keys [isup biopsy] :as perm}] (and (= (nccn-n-intermediate-risk-factors perm) 1) (< isup 3) (= biopsy 1))) (defn nccn-unfavorable [{:keys [isup biopsy] :as perm}] (or (<= 2 (nccn-n-intermediate-risk-factors perm) 3) (= isup 3) (= biopsy 2))) (defn nccn-high [{:keys [psa isup t-stage]}] (or (> isup 3) (> psa 20) (>= t-stage (t :t3)))) (defn nccn [m] (cond (nccn-high m) :high-risk (nccn-low m) :low-risk (nccn-favorable m) :favorable (nccn-unfavorable m) :unfavorable :else :uncategorized)) (def nccn-freqs (->> perms (map #(assoc % :nccn (nccn %))) (map :nccn) (frequencies))) (def percentages {:eau (add-percent perms eau-freqs) :nccn (add-percent perms nccn-freqs) :combinations (->> perms (map #(assoc % :eau (eau %))) (map #(assoc % :nccn (nccn %))) ;; (filter #(and (= (:eau %) :favorable) ;; (= (:nccn %) :unfavorable)))) (map #(assoc % :same? (= (:eau %) (:nccn %)))) (map (fn [p] [(:eau p) (:nccn p)])) (frequencies))}) percentages