(defn sample
" Returns a sample of the given size from the given collection. If replacement
is set to false it returns a set, otherwise it returns a list.
Arguments:
x -- collection to be sampled from
Options:
:size -- (default (count x) sample size
:replacement (default true) -- sample with replacement
Examples:
(sample (range 10)) ; permutation of numbers zero through ten
(sample [:red :green :blue] :size 10) ; choose 10 items that are either :red, :green, or :blue.
(sample (seq \"abcdefghijklmnopqrstuvwxyz\") :size 4 :replacement false) ; choose 4 random letters.
"
([x & options]
(let [opts (when options (apply assoc {} options))
size (or (:size opts) (count x))
replacement? (if (false? (:replacement opts)) false true)
max-idx (dec (count x))]
(if (= size 1)
(nth x (rand-int (inc max-idx)))
(if replacement?
(map #(nth x %) (sample-uniform size :min 0 :max max-idx :integers true))
(if (> size (count x))
(throw (Exception. "'size' can't be larger than (count x) without replacement!"))
(map #(nth x %)
(loop [samp-indices [] indices-set #{}]
(if (= (count samp-indices) size)
samp-indices
(let [i (sample-uniform 1 :min 0 :max max-idx :integers true)]
(if (contains? indices-set i)
(recur samp-indices indices-set)
(recur (conj samp-indices i) (conj indices-set i)))))))))))))
Used in 0 other vars
Comments top
No comments for sample. Log in to add a comment.