mapview mapview:::burstByRow on data.table
Hello,
it seems like mapview isn't able to hande sf data.tables when applying burst on a specific column.
Any ideas?
library('data.table')
library('sf')
#> Linking to GEOS 3.6.1, GDAL 2.2.3, proj.4 4.9.3
library('mapview')
# works on sf data.frame
brew_sf = breweries[1:5, ]
mapview(brew_sf, burst = "founded")

# crashes on sf data.table
brew_dt = as.data.table(breweries[1:5, ])
brew_dt = st_as_sf(brew_dt)
mapview(brew_dt, burst = "founded")
#> Error in `[.data.frame`(as.data.frame(x), , zcol): undefined columns selected
Created on 2018-09-11 by the reprex package (v0.2.0).
Session info
devtools::session_info()
#> Session info -------------------------------------------------------------
#> setting value
#> version R version 3.5.1 (2018-07-02)
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_United States.1252
#> tz Europe/Berlin
#> date 2018-09-11
#> Packages -----------------------------------------------------------------
#> package * version date source
#> backports 1.1.2 2017-12-13 CRAN (R 3.5.0)
#> base * 3.5.1 2018-07-02 local
#> base64enc 0.1-3 2015-07-28 CRAN (R 3.5.0)
#> class 7.3-14 2015-08-30 CRAN (R 3.5.0)
#> classInt 0.2-3 2018-04-16 CRAN (R 3.5.0)
#> colorspace 1.3-2 2016-12-14 CRAN (R 3.5.0)
#> compiler 3.5.1 2018-07-02 local
#> crosstalk 1.0.0 2016-12-21 CRAN (R 3.5.1)
#> curl 3.2 2018-03-28 CRAN (R 3.5.0)
#> data.table * 1.11.4 2018-05-27 CRAN (R 3.5.1)
#> datasets * 3.5.1 2018-07-02 local
#> DBI 1.0.0 2018-05-02 CRAN (R 3.5.1)
#> devtools 1.13.6 2018-06-27 CRAN (R 3.5.1)
#> digest 0.6.15 2018-01-28 CRAN (R 3.5.0)
#> e1071 1.7-0 2018-07-28 CRAN (R 3.5.1)
#> evaluate 0.11 2018-07-17 CRAN (R 3.5.1)
#> GIproxy 0.0.1 2018-07-10 local
#> graphics * 3.5.1 2018-07-02 local
#> grDevices * 3.5.1 2018-07-02 local
#> grid 3.5.1 2018-07-02 local
#> htmltools 0.3.6 2017-04-28 CRAN (R 3.5.0)
#> htmlwidgets 1.2 2018-04-19 CRAN (R 3.5.1)
#> httpuv 1.4.5 2018-07-19 CRAN (R 3.5.1)
#> httr 1.3.1 2017-08-20 CRAN (R 3.5.1)
#> jsonlite 1.5 2017-06-01 CRAN (R 3.5.1)
#> knitr 1.20 2018-02-20 CRAN (R 3.5.1)
#> later 0.7.3 2018-06-08 CRAN (R 3.5.0)
#> lattice 0.20-35 2017-03-25 CRAN (R 3.5.0)
#> leaflet 2.0.2 2018-08-27 CRAN (R 3.5.1)
#> magrittr 1.5 2014-11-22 CRAN (R 3.5.1)
#> mapview * 2.4.15 2018-08-08 Github (r-spatial/mapview@69be92e)
#> memoise 1.1.0 2017-04-21 CRAN (R 3.5.0)
#> methods * 3.5.1 2018-07-02 local
#> mime 0.5 2016-07-07 CRAN (R 3.5.0)
#> munsell 0.5.0 2018-06-12 CRAN (R 3.5.1)
#> png 0.1-7 2013-12-03 CRAN (R 3.5.0)
#> promises 1.0.1 2018-04-13 CRAN (R 3.5.0)
#> R6 2.2.2 2017-06-17 CRAN (R 3.5.0)
#> raster 2.6-7 2017-11-13 CRAN (R 3.5.0)
#> RColorBrewer 1.1-2 2014-12-07 CRAN (R 3.5.0)
#> Rcpp 0.12.18 2018-07-23 CRAN (R 3.5.1)
#> rmarkdown 1.10 2018-06-11 CRAN (R 3.5.1)
#> rprojroot 1.3-2 2018-01-03 CRAN (R 3.5.0)
#> satellite 1.0.1 2017-10-18 CRAN (R 3.5.0)
#> scales 1.0.0 2018-08-09 CRAN (R 3.5.1)
#> sf * 0.6-4 2018-08-08 Github (r-spatial/sf@bafc5b5)
#> shiny 1.1.0 2018-05-17 CRAN (R 3.5.1)
#> sp 1.3-1 2018-06-05 CRAN (R 3.5.1)
#> spData 0.2.9.3 2018-08-01 CRAN (R 3.5.1)
#> stats * 3.5.1 2018-07-02 local
#> stats4 3.5.1 2018-07-02 local
#> stringi 1.2.4 2018-07-20 CRAN (R 3.5.1)
#> stringr 1.3.1 2018-05-10 CRAN (R 3.5.1)
#> tools 3.5.1 2018-07-02 local
#> units 0.6-0 2018-06-09 CRAN (R 3.5.1)
#> utils * 3.5.1 2018-07-02 local
#> viridisLite 0.3.0 2018-02-01 CRAN (R 3.5.1)
#> webshot 0.5.0 2017-11-29 CRAN (R 3.5.0)
#> withr 2.1.2 2018-03-15 CRAN (R 3.5.1)
#> xml2 1.2.0 2018-01-24 CRAN (R 3.5.0)
#> xtable 1.8-2 2016-02-05 CRAN (R 3.5.0)
#> yaml 2.2.0 2018-07-25 CRAN (R 3.5.1)
Thanks @cstepper, this seems to be an edge case.
The problem is with the split method of data.table and trips here.
The following presents a hacky workaround:
library(mapview)
library(data.table)
# no problem
tst_dt = data.table::data.table(franconia)
split(tst_dt, f = tst_dt[["district"]])
# causes problem
tst_dt_sf = sf::st_as_sf(tst_dt)
split(tst_dt_sf, f = tst_dt_sf[["district"]])
# dirty hacky workaround - push class "data.table" to the end
dt_last = function(x) {
cls = class(x)
dtcls = grep("data.table", cls)
if (length(dtcls) == 0) return(x)
class(x) = c(cls[-dtcls], "data.table")
return(x)
}
class(tst_dt_sf)
class(dt_last(tst_dt_sf))
# now it works
split(dt_last(tst_dtsf), f = tst_dtsf[["district"]])
mapview(dt_last(tst_dtsf), zcol = "district", burst = TRUE)
While we could (and with regard to its scope should) implement such a workaround in mapview, I'd like to hear @edzer 's opinion on this one as he may have a more clever workaround? I am just not that familiar with all the details of class handling in R...
@edzer do you have any input here, regarding that this may well trip sf users outside of mapview too?
Would a split method for sf objects resolve this?
I think so, given that the class order is sf data.table data.frame
So this method should remove the sf and data.table classes, then call NextMethod()? Feels hacky, but if it works, it works.
Yeah, I don't see a better solution without importing data.table. even then it would involve some hacks.
Doing
as.data.frame > split > st_as_sf
doesn't feel too hacky IMO.
Fwiw we do such things all the time when working with sf and data.table.
That would also drop tbl_dfs.
Good point. This means that we need to re-assign classes after the operation, right?
We do that all the time, see for an example here.