<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 11 (filtered medium)">
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman";}
a:link, span.MsoHyperlink
        {color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {color:blue;
        text-decoration:underline;}
p.CBSectionHeader, li.CBSectionHeader, div.CBSectionHeader
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:Arial;
        font-weight:bold;}
p.CBSub-section, li.CBSub-section, div.CBSub-section
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman";
        font-weight:bold;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:Arial;
        color:navy;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
        {page:Section1;}
-->
</style>

</head>

<body lang=EN-US link=blue vlink=blue>

<div class=Section1>

<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>David,<o:p></o:p></span></font></p>

<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Yeah, that is why I set it up to pass the
seed in as the third parameter. I would be interested in including any other R
functional implementations that you have in the library that I am maintaining,
if you are interested in sharing them.<o:p></o:p></span></font></p>

<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'><o:p> </o:p></span></font></p>

<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>r.b.<o:p></o:p></span></font></p>

<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'><o:p> </o:p></span></font></p>

<div>

<div class=MsoNormal align=center style='text-align:center'><font size=3
face="Times New Roman"><span style='font-size:12.0pt'>

<hr size=2 width="100%" align=center tabindex=-1>

</span></font></div>

<p class=MsoNormal><b><font size=2 face=Tahoma><span style='font-size:10.0pt;
font-family:Tahoma;font-weight:bold'>From:</span></font></b><font size=2
face=Tahoma><span style='font-size:10.0pt;font-family:Tahoma'>
postgis-users-bounces@postgis.refractions.net
[mailto:postgis-users-bounces@postgis.refractions.net] <b><span
style='font-weight:bold'>On Behalf Of </span></b>David William Bitner<br>
<b><span style='font-weight:bold'>Sent:</span></b> Thursday, January 25, 2007
11:59 AM<br>
<b><span style='font-weight:bold'>To:</span></b> PostGIS Users Discussion<br>
<b><span style='font-weight:bold'>Subject:</span></b> Re: [postgis-users]
quantiles, quartiles, or jenks natural</span></font><o:p></o:p></p>

</div>

<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'><o:p> </o:p></span></font></p>

<p class=MsoNormal style='margin-bottom:12.0pt'><font size=3
face="Times New Roman"><span style='font-size:12.0pt'>Robert,<br>
<br>
If you don't pass the set.seed, R will use a random seed already I
believe.  The reason I use it with the same seed is that I had a need to
be able to run the query multiple times on the same data and be sure I would
get the same results.  I've had great success using this approach with a
number of different R functions. <br>
<br>
I'm glad to see that you are getting some use out of it too.<br>
<br>
David<o:p></o:p></span></font></p>

<div>

<p class=MsoNormal><span class=gmailquote><font size=3 face="Times New Roman"><span
style='font-size:12.0pt'>On 1/25/07, <b><span style='font-weight:bold'>Robert
Burgholzer</span></b> <<a href="mailto:rburghol@chesapeakebay.net">
rburghol@chesapeakebay.net</a>> wrote:</span></font></span><o:p></o:p></p>

<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'>David/others,<br>
I have finally revisited this thread, having forgotten all about it, and <br>
missing the finale. I wish I had realized you solved my problem already<br>
(with your array_accum), as I came up with a less elegant solution --<br>
after hours of struggle :).<br>
<br>
Anyhow, I have modified your "kmeans" function slightly to make it a
bit <br>
more robust (I think), allowing it to use decimals instead of integers,<br>
and allowing you to pass in the seed value yourself (assuming that some<br>
utility exists in being able to supply a random, rather than static, <br>
seed). That said, I don't really know if kmeans is supposed to act on<br>
non-integer values, but it seems to behave OK.<br>
<br>
CREATE OR REPLACE FUNCTION kmeans(double precision[], int4, int4)<br>
  RETURNS double precision[] AS' <br>
set.seed(arg3)<br>
km=kmeans(sort(arg1),arg2)<br>
sort(unlist(tapply(sort(arg1),factor(match(km$cluster,order(km$centers))<br>
),range)))<br>
' LANGUAGE 'plr' VOLATILE STRICT;<br>
<br>
I have posted this code, as well as an implementation of the
"quantile" <br>
function (now using your more robust array_accum implementation) at:<br>
<br>
<a href="http://soulswimmer.dynalias.net/db/R/r_functions.01.sql">http://soulswimmer.dynalias.net/db/R/r_functions.01.sql</a><br>
<br>
Comments, suggestions, and other R function implementations are most <br>
welcome.<br>
<br>
r.b.<br>
<br>
<br>
-----Original Message-----<br>
From: <a href="mailto:postgis-users-bounces@postgis.refractions.net">postgis-users-bounces@postgis.refractions.net</a><br>
[mailto:<a href="mailto:postgis-users-bounces@postgis.refractions.net">
postgis-users-bounces@postgis.refractions.net</a>] On Behalf Of<br>
David Bitner<br>
Sent: Thursday, March 02, 2006 12:45 PM<br>
To: PostGIS Users Discussion<br>
Subject: Re: [postgis-users] quantiles, quartiles, or jenks natural <br>
<br>
By the way, the set.seed call is so I get the same results with<br>
subsequent calls on the dataset as I make one call with PHP and<br>
PostgreSQL to the database to create my legend with the class<br>
intervals and another to divvy up my dataset into predefined class <br>
styles in my mapfile with MapServer and I need subsequent calls to<br>
come up with the same results.<br>
<br>
On 3/2/06, David Bitner <<a href="mailto:osgis.lists@gmail.com">osgis.lists@gmail.com</a>>
wrote:<br>
> The main function that I made is kmeans which takes an array of the <br>
> values that you want to classify and the number of classes that you<br>
> want and spits out an array of the break points for the data.<br>
><br>
> For example:<br>
> select<br>
kmeans(array[1,1,1,1,4,3,5,6,45,3,5,7,8,6,4,3,2,1,32,6,7,5,6,7,8],4) <br>
> returns<br>
> {1,2,3,4,5,8,32,45}<br>
> which can be interpreted as use these classes:<br>
> 1-2,3-4,5-8,32-45<br>
> which extending to have no gaps would be the same as either<br>
> 1-2,3-4,5-31,32-45 or <br>
> 1-2,3-4,5-8,9-45<br>
><br>
> I generally just call this using an array_accum aggregate like this:<br>
> select kmeans(array_accum(myintegercol),4)  from mytable<br>
><br>
> As I said before, I kept getting some parse errors that I haven't had <br>
> time to look into when I tried writing the function to multiple lines,<br>
> so the function is all one line.<br>
><br>
> CREATE OR REPLACE FUNCTION kmeans(_int8, int4)<br>
>   RETURNS _int8 AS<br>
><br>
'set.seed(2007);km=kmeans(sort(arg1),arg2);sort(unlist(tapply(sort(arg1)<br>
,factor(match(km$cluster<br>
> ,order(km$centers))),range)))'<br>
>   LANGUAGE 'plr' VOLATILE STRICT;<br>
><br>
> CREATE AGGREGATE array_accum( <br>
>   BASETYPE=anyelement,<br>
>   SFUNC=array_append,<br>
>   STYPE=anyarray,<br>
>   INITCOND='{}'<br>
> );<br>
><br>
><br>
><br>
> On 3/2/06, Stephen Woodbridge <<a href="mailto:woodbri@swoodbridge.com">
woodbri@swoodbridge.com</a>> wrote:<br>
> > David,<br>
> ><br>
> > Please post it to the listserv, I would be interested also. I have<br>
yet<br>
> > to jump into PL/R but it is on my list to do.<br>
> ><br>
> > Thanks,<br>
> >    -Steve<br>
> ><br>
> > David Bitner wrote:<br>
> > > I ended up jumping into the PL/R world and just created an<br>
aggregate<br>
> > > wrapper around kmeans to get my class values. They ended up
being <br>
> > > very, very close (identical in some cases) to classifications
that<br>
had<br>
> > > been done with Jenks Natural Breaks.  If you want the
same results<br>
> > > every time you run a classification on the same data, you need
to <br>
set<br>
> > > the same seed value for the random number generator before each<br>
run.<br>
> > ><br>
> > > It's pretty basic and my code is ugly due to some R parser
errors<br>
that<br>
> > > I could only get passed by throwing all the code on one line
with <br>
no<br>
> > > spaces (hey it worked and I didn't have time to look into the<br>
parser<br>
> > > error), but I can throw the code up if anyone would like.<br>
> > ><br>
> > > On 3/2/06, Robert Burgholzer < <a
href="mailto:rburghol@chesapeakebay.net">rburghol@chesapeakebay.net</a>> wrote:<br>
> > ><br>
> > >>OK,<br>
> > >>I'm coming into this late, but I am a user of PL/R and
PostGIS,<br>
and<br>
> > >>would appreciate any progress on developing some
classification<br>
routines<br>
> > >>to be posted to this lists, or I would be interested in being<br>
notified<br>
> > >>offline. <br>
> > >><br>
> > >>Thanks!<br>
> > >><br>
> > >>r.b.<br>
> > >><br>
> > >>-----Original Message-----<br>
> > >>From: <a
href="mailto:postgis-users-bounces@postgis.refractions.net">postgis-users-bounces@postgis.refractions.net</a><br>
> > >>[mailto:<a
href="mailto:postgis-users-bounces@postgis.refractions.net">postgis-users-bounces@postgis.refractions.net</a>]
On Behalf<br>
Of Amit<br>
> > >>Kulkarni <br>
> > >>Sent: Wednesday, March 01, 2006 1:20 PM<br>
> > >>To: <a href="mailto:postgis-users@postgis.refractions.net">postgis-users@postgis.refractions.net</a><br>
> > >>Subject: Re: [postgis-users] quantiles, quartiles, or jenks <br>
natural<br>
> > >><br>
> > >>Sorry, I have been catching up on the past few months emails.
I<br>
just<br>
> > >>want to add that I read that quantiles and minimum boundary
error<br>
are<br>
> > >>better than jenks. Also minimum boundary error takes into
account<br>
the<br>
> > >>underlying topology.<br>
> > >><br>
> > >>The two being better are mentioned in<br>
> > >> <br>
> > >>Brewer, Cynthia A. & Pickle, Linda (2002) Evaluation of
Methods<br>
for<br>
> > >>Classifying Epidemiological Data on Choropleth Maps in
Series.<br>
> > >>Annals of the Association of American Geographers 92 (4),
662-681 <br>
> > >><br>
> > >>And the minimum boundary algorithm is supposedly mentioned in<br>
> > >><br>
> > >>Cromley, E. K. , and R. G. Cromley. 1996. An analysis of<br>
alternative<br>
> >
>>classification  schemes  for  medical  atlas
mapping. European<br>
Journal<br>
> > >>of Cancer 32A (9): 1551 -- 59.<br>
> > >><br>
> > >>Cromley, R. G. , and R. D. Mrozinski. 1999. The
classification of <br>
> > >>ordinal data for choropleth mapping. The Cartographic Journal
36<br>
(2):<br>
> > >>101 -- 9.<br>
> > >><br>
> > >>HTH,<br>
> > >>amit<br>
> > >> <br>
> > >><br>
> > >>Date: Tue, 14 Feb 2006 12:38:39 -0800<br>
> > >>From: Paul Ramsey <<a href="mailto:pramsey@refractions.net">pramsey@refractions.net</a>><br>
> > >><br>
> > >>I did some in PHP, but the algorithms are relatively
braindead,<br>
the<br>
> > >>quantile stuff in particular.  Jenks I did some
research on but<br>
never<br>
> > >>really found a definitive description of the
process.  Some of the <br>
> > >>descriptions ended up sounding like a k-means clustering
idea,<br>
which<br>
> > >>is not cheap!<br>
> > >><br>
> > >>P.<br>
> > >><br>
> > >>__________________________________________________ <br>
> > >>Do You Yahoo!?<br>
> > >>Tired of spam?  Yahoo! Mail has the best spam
protection around<br>
> > >><a href="http://mail.yahoo.com">http://mail.yahoo.com</a><br>
> > >>_______________________________________________ <br>
> > >>postgis-users mailing list<br>
> > >><a href="mailto:postgis-users@postgis.refractions.net">postgis-users@postgis.refractions.net</a><br>
> > >><a
href="http://postgis.refractions.net/mailman/listinfo/postgis-users">
http://postgis.refractions.net/mailman/listinfo/postgis-users</a><br>
> > >>_______________________________________________<br>
> > >>postgis-users mailing list<br>
> > >><a href="mailto:postgis-users@postgis.refractions.net">
postgis-users@postgis.refractions.net</a><br>
> > >><a
href="http://postgis.refractions.net/mailman/listinfo/postgis-users">http://postgis.refractions.net/mailman/listinfo/postgis-users</a><br>
> > >> <br>
> > ><br>
> > > _______________________________________________<br>
> > > postgis-users mailing list<br>
> > > <a href="mailto:postgis-users@postgis.refractions.net">postgis-users@postgis.refractions.net
</a><br>
> > > <a
href="http://postgis.refractions.net/mailman/listinfo/postgis-users">http://postgis.refractions.net/mailman/listinfo/postgis-users</a><br>
> > ><br>
> ><br>
> > _______________________________________________ <br>
> > postgis-users mailing list<br>
> > <a href="mailto:postgis-users@postgis.refractions.net">postgis-users@postgis.refractions.net</a><br>
> > <a
href="http://postgis.refractions.net/mailman/listinfo/postgis-users">http://postgis.refractions.net/mailman/listinfo/postgis-users</a><br>
> ><br>
><br>
_______________________________________________<br>
postgis-users mailing list<br>
<a href="mailto:postgis-users@postgis.refractions.net">postgis-users@postgis.refractions.net</a><br>
<a href="http://postgis.refractions.net/mailman/listinfo/postgis-users">http://postgis.refractions.net/mailman/listinfo/postgis-users</a><br>
_______________________________________________ <br>
postgis-users mailing list<br>
<a href="mailto:postgis-users@postgis.refractions.net">postgis-users@postgis.refractions.net</a><br>
<a href="http://postgis.refractions.net/mailman/listinfo/postgis-users">http://postgis.refractions.net/mailman/listinfo/postgis-users
</a><o:p></o:p></span></font></p>

</div>

<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'><br>
<br clear=all>
<br>
-- <br>
************************************<br>
David William Bitner <o:p></o:p></span></font></p>

</div>

</body>

</html>