From 3b19dc04b14e27a12a3152d0cc3a52d1048854a8 Mon Sep 17 00:00:00 2001 From: Munyoki Kilyungi Date: Fri, 29 Jul 2022 15:57:34 +0300 Subject: Add new functions to read CSV files in a flexible way. We add new functions---parse-raw-table and parse-aggregate-table---to parse raw ungrouped data and grouped data respectively. * csv-dump.scm (assoc-set, parse-raw-table, parse-aggregate-table): New functions. Signed-off-by: Arun Isaac --- csv-dump.scm | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 csv-dump.scm diff --git a/csv-dump.scm b/csv-dump.scm new file mode 100644 index 0000000..a2a9127 --- /dev/null +++ b/csv-dump.scm @@ -0,0 +1,66 @@ +(use-modules (srfi srfi-1) + (ice-9 match) + (ice-9 rdelim) + (dsv)) + +(define (assoc-set alist key value) + "Associate KEY with VALUE in ALIST, and return the new association +list. This is a functional setter and does not mutate ALIST. KEY is +compared with keys in ALIST using equal?." + (acons key value + (alist-delete key alist))) + +(define (parse-aggregate-table table) + "Convert TABLE from the provided aggregate file to an s-exp equivalent. +The GROUP forms the KEY of each alist." + (match table + ((header table-body ...) + (fold (lambda (row results) + (let ((alist (map cons header row))) + (acons (string->symbol (assoc-ref alist "group")) + (filter-map (lambda (key value) + (and (member key + (list "mean" "n" "sex " "SD" "day")) + (cons (string->symbol (string-downcase key)) + value))) + header row) + results))) + '() + table-body)))) + +(define (parse-raw-table table aggregate-table) + "Given TABLE which represents the data from the raw file, and the +AGGREGATE-TABLE which is an ALIST containing aggregate data, add extra +metadata not present in the aggregate table and return this result." + (match table + ((header table-body ...) + (fold (lambda (row results) + (let* ((alist (map cons header row)) + (key (string->symbol (string-join + (list (assoc-ref alist "strain") + (assoc-ref alist "sex") + (assoc-ref alist "day")) + "_"))) + (aggregate-data (assq-ref aggregate-table key)) + (folded-data (assq-ref results key))) + ;; Return an updated version of the aggregate-table as + ;; you loop through the raw table. Do this while + ;; collecting the values for 'bw and setting 'inf-dose + (assoc-set results + key (assoc-set + ;; inf_dose is repetitive in raw table + ;; and it's common in the same vector + ;; of data. If it isn't set, set it + ;; once. + (if (assq-ref folded-data 'aggregate-dose) + aggregate-data + (acons 'inf-dose (assoc-ref alist "inf_dose") aggregate-data)) + 'bw + ;; When looping in the raw table, + ;; collect all the 'bw values. + (if (assq-ref folded-data 'bw) + (cons (assoc-ref alist "BW") + (assq-ref folded-data 'bw)) + (list (assoc-ref alist "BW"))))))) + '() + table-body)))) -- cgit v1.2.3