I propose an enhancement of xsl:for-each-group to support clustering.
To start off with a simple use case, suppose one has the following population, <xsl:variable name="ages" as="xs:integer*" select="5, 24, 9, 5, 6, 8, 36, 38, 28"/> and one wishes to cluster the figures like so, in four groups: (5, 5, 6, 8, 9), (24), (28), (36, 38).
One is tempted to create an <xsl:for-each-group> with group-by="((. - 1) to (. + 1))". But this does not work. If @composite is absent or is no, eighteen groups are created. If @composite is yes, eight groups are created. In both cases, the results are not significantly close to the desired output.
I propose a new @group-by-cluster. The following code
<xsl:for-each-group select="$ages" group-by-cluster="((. - 1) to (. + 1))">
<xsl:sort select="current-grouping-key()"/>
<group key="{current-grouping-key()}" count="{count(current-group())}">
<xsl:copy-of select="current-group()"/>
</group>
</xsl:for-each-group>
would produce this
<group key="4 5 6 7 8 9 10" count="2">5 5 6 8 9</group>
<group key="23 24 25" count="1">24</group>
<group key="27 28 29" count="1">28</group>
<group key="35 36 37 38 39" count="1">36 38</group>
There are numerous use cases for the proposed new feature. Here are a few:
- Clustering map or spatial coordinates
- Grouping disparate rectangles from OCR output
- Reconciling triples in linked open data (RDF) that use different IRIs synonymously
- Detecting typologies within in large corpora of documents that have periodically repetitive formulaic paragraphs.
- Discovering networks of connected things, e.g., networks of email correspondence or publication citations
Currently, the clustering I describe above is feasible in XSLT, but it requires creative strategies, usually a combination of preprocessing and the creation of specialized helper functions to recursively iterate over multiple grouping keys to create group numbers. These are challenging to write and debug, and one loses identity in a preprocessed copy of the original.
By putting clustering into a @group-by-cluster construct, users benefit not only from convenience but also from performance, as a processor might bring novel strategies for clustering.
The current-grouping-key() for a group would consist of a sequence of all members' grouping keys, duplicates removed. No two groups would have any overlap in their grouping key sequences. (That's the definition of a cluster.)
@group-by-cluster would have effect only if its value actually produced a sequence of length greater than one, and if @composite is no. (Should a user should be warned if @composite is yes?)
I propose an enhancement of
xsl:for-each-groupto support clustering.To start off with a simple use case, suppose one has the following population,
<xsl:variable name="ages" as="xs:integer*" select="5, 24, 9, 5, 6, 8, 36, 38, 28"/>and one wishes to cluster the figures like so, in four groups:(5, 5, 6, 8, 9),(24),(28),(36, 38).One is tempted to create an
<xsl:for-each-group>withgroup-by="((. - 1) to (. + 1))". But this does not work. If@compositeis absent or isno, eighteen groups are created. If@compositeisyes, eight groups are created. In both cases, the results are not significantly close to the desired output.I propose a new
@group-by-cluster. The following codewould produce this
There are numerous use cases for the proposed new feature. Here are a few:
Currently, the clustering I describe above is feasible in XSLT, but it requires creative strategies, usually a combination of preprocessing and the creation of specialized helper functions to recursively iterate over multiple grouping keys to create group numbers. These are challenging to write and debug, and one loses identity in a preprocessed copy of the original.
By putting clustering into a
@group-by-clusterconstruct, users benefit not only from convenience but also from performance, as a processor might bring novel strategies for clustering.The
current-grouping-key()for a group would consist of a sequence of all members' grouping keys, duplicates removed. No two groups would have any overlap in their grouping key sequences. (That's the definition of a cluster.)@group-by-clusterwould have effect only if its value actually produced a sequence of length greater than one, and if@compositeis no. (Should a user should be warned if@compositeis yes?)