mapview icon indicating copy to clipboard operation
mapview copied to clipboard

mapview mapview:::burstByRow on data.table

Open cstepper opened this issue 7 years ago • 9 comments

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)

cstepper avatar Sep 11 '18 12:09 cstepper

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...

tim-salabim avatar Sep 11 '18 20:09 tim-salabim

@edzer do you have any input here, regarding that this may well trip sf users outside of mapview too?

tim-salabim avatar Sep 16 '18 11:09 tim-salabim

Would a split method for sf objects resolve this?

edzer avatar Sep 16 '18 16:09 edzer

I think so, given that the class order is sf data.table data.frame

tim-salabim avatar Sep 16 '18 16:09 tim-salabim

So this method should remove the sf and data.table classes, then call NextMethod()? Feels hacky, but if it works, it works.

edzer avatar Sep 16 '18 17:09 edzer

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.

tim-salabim avatar Sep 16 '18 18:09 tim-salabim

That would also drop tbl_dfs.

edzer avatar Sep 16 '18 20:09 edzer

Good point. This means that we need to re-assign classes after the operation, right?

tim-salabim avatar Sep 16 '18 20:09 tim-salabim

We do that all the time, see for an example here.

edzer avatar Sep 16 '18 20:09 edzer