rpivotTable
, randgeo
, and other great pkgspivottable
and turfjs
I had this idea yesterday afternoon as I combined Tom MacWright's library simple-statistics
for custom aggregation in Nicolas Kructhen's amazing pivottable
. Well, Tom works at Mapbox, and I have been doing some geo recently, so I thought
**Wouldn't a geo pivot table be something amazing?! **
For those that don't know, many fine folks at Mapbox make another fantastic open source library turf
which can provide pivottable aggregators for geo features. I'll put it all together in R
using the htmlwidget rpivotTable
. The R package randgeo
will supply some random polygons as seed data. This idea deserves much better than this quick sketch, but for now offer a centroid
and centerOfMass
aggregator.
library(rpivotTable)
library(tibble)
library(randgeo)
library(htmltools)
library(dplyr)
n = 30
df_geos <- tibble(
ltr_cat = letters[floor(runif(n, 1, 5))],
rand_poly = lapply(1:n, function(x) {geo_polygon(count=10)})
)
rpvt <- rpivotTable(
df_geos,
aggregators = htmlwidgets::JS(
'{turf_centroid: turf_centroid(), turf_centermass: turf_centermass()}'
)
)
# rpivotTable auto boxes everything except inclusions and exclusions
# https://github.com/smartinsightsfromdata/rpivotTable/blame/master/R/rpivotTable.R#L110-L117
# so we need to unbox or unlist
rpvt$x$params$aggregators <- rpvt$x$params$aggregators[[1]]
tagList(
tags$script(src = "https://unpkg.com/@turf/turf/turf.min.js"),
tags$script(
"
var turf_centroid = function(formatter) {
if (formatter == null) {
formatter = function(d){return JSON.stringify(d)}
}
return function(arg) {
var attr;
attr = arg[0];
return function(data, rowKey, colKey) {
return {
arr: [],
push: function(record) {
var that = this;
if(attr) {record[attr].features.forEach(function(d) {that.arr.push(d)});}
},
value: function() {
return typeof(this.arr[0]) !== 'undefined' ?
turf.centroid(turf.featureCollection(this.arr)) :
null;
},
format: formatter,
numInputs: attr != null ? 0 : 1
};
};
};
}
var turf_centermass = function(formatter) {
if (formatter == null) {
formatter = function(d){return JSON.stringify(d)}
}
return function(arg) {
var attr;
attr = arg[0];
return function(data, rowKey, colKey) {
return {
arr: [],
push: function(record) {
var that = this;
if(attr) {record[attr].features.forEach(function(d) {that.arr.push(d)});}
},
value: function() {
return this.arr.length ?
turf.centerOfMass(turf.featureCollection(this.arr)) :
null;
},
format: formatter,
numInputs: attr != null ? 0 : 1
};
};
};
}
"
),
rpvt
) %>%
browsable()
I would love any help, ideas, feedback, examples. Please let me know what you are thinking.