18 Aug 2015
Measuring things
I use org-mode for registering the books I read. Here some code to produce stats.
;; Is there a better (more idiomatic) way to aggregate values?
(defun aggregate (aggregate-function lst)
(let ((hash (make-hash-table :test 'equal)))
(loop for key in (mapcar 'car lst)
for value in (mapcar 'cdr lst)
do (if (null (gethash key hash))
(puthash key value hash)
(puthash key (funcall aggregate-function value (gethash key hash)) hash))
finally return hash)))
(defun pages-per-month-raw ()
(with-current-buffer (get-file-buffer "~/org/books.org")
(mapcar (lambda (b)
(let* ((month (format-time-string "%b" (date-to-time (cdr (assoc "TIMESTAMP" b)))))
(pages (string-to-int (cdr (assoc "PAGES" b)))))
(cons month pages)))
(books/in-year "2015"))))
(defun pages-per-month ()
(let ((ppmr (pages-per-month-raw)))
(aggregate '+ ppmr)))
(defun month-list ()
'("Jan" "Feb" "Mar" "Apr" "May" "Jun"
"Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
(defun complete-hash (hash)
(let ((new-hash (make-hash-table)))
(loop for month-name in (month-list)
do (if (null (gethash month-name hash))
(puthash month-name 0 new-hash)
(puthash month-name (gethash month-name hash) new-hash))
finally return new-hash)))
;; Poor man's TSV export
;; TODO check the implicit assertion on the ordering
(maphash (lambda (k v) (insert (format "%s\t%s\n" k v)))
(complete-hash (pages-per-month)))
Then, for example:
stats <- read.csv("/tmp/stats.tsv", sep = "\t", header = F)
names(stats) <- c("month", "pages")
stats$month <- factor(stats$month, month.name )
p <- ggplot( stats, aes(month, pages)) +
geom_histogram() +
theme(axis.text.x = element_text(angle=45, hjust=1))
p
Tags: