From: jmckitrick
Subject: Better way to solve this problem?
Date: 
Message-ID: <1178037734.378812.84780@u30g2000hsc.googlegroups.com>
I have a list of data items where each item is a list of an item
number and a vector of integers.  I need to perform a handful of
statistics operations on the vectors in each data item.

Here's what I'm doing now:

(defun calculate-stat (statistic-function item/responses)
  (mapcar (lambda (item/response)
	    (push (format nil "~,2f"
			  (handler-case
			      (funcall statistic-function (car (last item/response)))
			    (division-by-zero () "-")))
		  item/response))
	  item/responses))

(defun calculate-stats (tool)
  (let ((item/responses (get-tool-response-set tool))
	(statistic-functions '(mean median sd)))
    (dolist (stat-function statistic-functions)
      (setf item/responses (calculate-stat stat-function item/
responses)))
    (setf item/responses (mapcar #'reverse item/responses))
    (mapcar (lambda (item/response) (remove (first item/response) item/
response))
	    item/responses)))

The end result is a list of items, where each item is a list of item
number and the MEAN, MEDIAN, and SD of the vector item.  I no longer
need the vector of data for each item.

It seems there should be a cleaner way to do this.  Any suggestions?

From: Geoffrey Summerhayes
Subject: Re: Better way to solve this problem?
Date: 
Message-ID: <1178043122.665297.282310@n76g2000hsh.googlegroups.com>
On May 1, 12:42 pm, jmckitrick <···········@yahoo.com> wrote:
> I have a list of data items where each item is a list of an item
> number and a vector of integers.  I need to perform a handful of
> statistics operations on the vectors in each data item.
>
> Here's what I'm doing now:
>
> (defun calculate-stat (statistic-function item/responses)
>   (mapcar (lambda (item/response)
>             (push (format nil "~,2f"
>                           (handler-case
>                               (funcall statistic-function (car (last item/response)))
>                             (division-by-zero () "-")))
>                   item/response))
>           item/responses))
>
> (defun calculate-stats (tool)
>   (let ((item/responses (get-tool-response-set tool))
>         (statistic-functions '(mean median sd)))
>     (dolist (stat-function statistic-functions)
>       (setf item/responses (calculate-stat stat-function item/
> responses)))
>     (setf item/responses (mapcar #'reverse item/responses))
>     (mapcar (lambda (item/response) (remove (first item/response) item/
> response))
>             item/responses)))
>
> The end result is a list of items, where each item is a list of item
> number and the MEAN, MEDIAN, and SD of the vector item.  I no longer
> need the vector of data for each item.
>
> It seems there should be a cleaner way to do this.  Any suggestions?

Untested, but maybe..

(defun calculate-stat(fn list)
  (format nil "~,2f"
          (handler-case
              (funcall statistic-function list)
            (division-by-zero () "-"))))

(defun calculate-stats (tool)
  (let ((item-sets (get-tool-response-set tool))
        (statistic-functions '(mean median sd)))
    (loop for item-set in items-sets
          collecting (cons (car item-set)
                           (loop for fn in statistic-functions
                                 collecting (calculate-stat fn (cadr
item-set)))))))

?
-----
Geoff
From: Rainer Joswig
Subject: Re: Better way to solve this problem?
Date: 
Message-ID: <joswig-C5FC19.21013601052007@news-europe.giganews.com>
In article <························@n76g2000hsh.googlegroups.com>,
 Geoffrey Summerhayes <·······@gmail.com> wrote:

> On May 1, 12:42 pm, jmckitrick <···········@yahoo.com> wrote:
> > I have a list of data items where each item is a list of an item
> > number and a vector of integers.  I need to perform a handful of
> > statistics operations on the vectors in each data item.
> >
> > Here's what I'm doing now:
> >
> > (defun calculate-stat (statistic-function item/responses)
> >   (mapcar (lambda (item/response)
> >             (push (format nil "~,2f"
> >                           (handler-case
> >                               (funcall statistic-function (car (last item/response)))
> >                             (division-by-zero () "-")))
> >                   item/response))
> >           item/responses))
> >
> > (defun calculate-stats (tool)
> >   (let ((item/responses (get-tool-response-set tool))
> >         (statistic-functions '(mean median sd)))
> >     (dolist (stat-function statistic-functions)
> >       (setf item/responses (calculate-stat stat-function item/
> > responses)))
> >     (setf item/responses (mapcar #'reverse item/responses))
> >     (mapcar (lambda (item/response) (remove (first item/response) item/
> > response))
> >             item/responses)))
> >
> > The end result is a list of items, where each item is a list of item
> > number and the MEAN, MEDIAN, and SD of the vector item.  I no longer
> > need the vector of data for each item.
> >
> > It seems there should be a cleaner way to do this.  Any suggestions?
> 
> Untested, but maybe..
> 
> (defun calculate-stat(fn list)
>   (format nil "~,2f"
>           (handler-case
>               (funcall statistic-function list)
>             (division-by-zero () "-"))))
> 
> (defun calculate-stats (tool)
>   (let ((item-sets (get-tool-response-set tool))
>         (statistic-functions '(mean median sd)))
>     (loop for item-set in items-sets
>           collecting (cons (car item-set)
>                            (loop for fn in statistic-functions
>                                  collecting (calculate-stat fn (cadr
> item-set)))))))
> 
> ?
> -----
> Geoff

also note that you can do destructuring in LOOP like this:

(LOOP FOR (n vector) in item-sets ...

-- 
http://lispm.dyndns.org