Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Affine transformation using mutate() #903

Closed
Nowosad opened this issue Nov 24, 2018 · 13 comments
Closed

Affine transformation using mutate() #903

Nowosad opened this issue Nov 24, 2018 · 13 comments

Comments

@Nowosad
Copy link
Contributor

Nowosad commented Nov 24, 2018

Continuing a discussion from twitter (https://twitter.com/edzerpebesma/status/1066051809347870720):

The main idea is to allow each feature to be scaled independently:

library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.3.2, PROJ 4.9.3
library(dplyr)
library(spData)

nz1 = nz %>% 
        mutate(scale = seq(0.2, 1, length.out = nrow(nz)))

# works
nz2 = nz1 %>% 
        mutate(geom = geom * 0.5)

# does not work
nz3 = nz1 %>% 
        mutate(geom = geom * scale)
#> Error in mutate_impl(.data, dots): Evaluation error: non-conformable arguments.

# does not work
nz4 = nz1 %>% 
        rowwise() %>% 
        mutate(geom = geom * scale)
#> Error in mutate_impl(.data, dots): Column `geom` must be length 1 (the group size), not 3

Created on 2018-11-24 by the reprex package (v0.2.1)

edzer added a commit that referenced this issue Nov 24, 2018
@edzer
Copy link
Member

edzer commented Nov 24, 2018

With this, your first "does not work" should now work, I assume that was what you were looking for. Note the newly created ambiguity of

library(sf)
# Linking to GEOS 3.6.2, GDAL 2.2.3, PROJ 4.9.3
sfc = st_sfc(st_point(0:1), st_point(2:3))
sfc + c(2,3) # add single 2D point to EACH geometry
# Geometry set for 2 features 
# geometry type:  POINT
# dimension:      XY
# bbox:           xmin: 2 ymin: 4 xmax: 4 ymax: 6
# epsg (SRID):    NA
# proj4string:    NA
# POINT (2 4)
# POINT (4 6)
sfc * c(2,3) # first geometry multiplied by 2, second by 3
# Geometry set for 2 features 
# geometry type:  POINT
# dimension:      XY
# bbox:           xmin: 0 ymin: 2 xmax: 6 ymax: 9
# epsg (SRID):    NA
# proj4string:    NA
# POINT (0 2)
# POINT (6 9)

Cc: @mdsumner

@mdsumner
Copy link
Member

Ugh- yeah that's a bit of a screwdriver in the works, I don't see a good solution

@edzer
Copy link
Member

edzer commented Nov 24, 2018

I documented it.

@mdsumner
Copy link
Member

Oh great, thanks for doing this @edzer !

@Nowosad
Copy link
Contributor Author

Nowosad commented Nov 25, 2018

I've tested it on a few cases and it worked as expected. It is a great improvement.
There is one issue I've found though - geom_sf() has some problems with transformed data. Base graphics and tmap works fine:

@edzer should I open a new issue on ggplot2 or keep it here?

library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.3.2, PROJ 4.9.3
library(dplyr)
library(spData)

new_nz = nz %>% 
        mutate(scale = seq(0.2, 1, length.out = nrow(nz))) %>% 
        mutate(geom = geom * scale)


# plotting ----------------------------------------------------------------
library(tmap)
library(ggplot2)
# base plot ---------------------------------------------------------------
plot(new_nz["Median_income"])

# tmap plot ---------------------------------------------------------------
tm_shape(new_nz) + tm_polygons("Median_income")
#> Warning: Current projection of shape new_nz unknown and cannot be
#> determined.
#> Warning: unknown projection
#> Legend labels were too wide. The labels have been resized to 0.26, 0.26, 0.26, 0.26, 0.26, 0.26. Increase legend.width (argument of tm_layout) to make the legend wider and therefore the labels larger.

# ggplot ------------------------------------------------------------------
ggplot() + geom_sf(data = new_nz, aes(fill = Median_income))

Created on 2018-11-25 by the reprex package (v0.2.1)

@edzer
Copy link
Member

edzer commented Nov 25, 2018

Let's try to sort out what happens first.

IIRC, by transforming it sf strips the CRS (i.e., sets it to NA) since you did some transformation outside the CRS framework (WKT / PROJ). geom_sf may make some hard assumption about the CRS it is in, as it will forcably assume your data have world coordinates. Maybe you need to put it back to the starting CRS first?

@edzer
Copy link
Member

edzer commented Nov 25, 2018

Forget my previous message: it looks like geom_sf relies on behaviour that worked previous to f20a583 but no longer works. We'll need to revert the fix.

@edzer
Copy link
Member

edzer commented Nov 25, 2018

Which I just did: 9fe41f2 . Sorry for the bad news.

@mdsumner
Copy link
Member

It's not an anti meridian problem?

@edzer
Copy link
Member

edzer commented Nov 25, 2018

No, everywhere -- I think it is in ggplot2:::sf_rescale01 (which I suggested...)

@Nowosad
Copy link
Contributor Author

Nowosad commented Nov 25, 2018

edzer added a commit that referenced this issue Nov 25, 2018
@Nowosad
Copy link
Contributor Author

Nowosad commented Nov 25, 2018

Looks good now:

library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.3.2, PROJ 4.9.3
library(dplyr)
library(spData)

new_nz = nz %>% 
        mutate(scale = seq(0.2, 1, length.out = nrow(nz))) %>% 
        mutate(geom = geom * scale)


# plotting ----------------------------------------------------------------
library(tmap)
library(ggplot2)
# base plot ---------------------------------------------------------------
plot(new_nz["Median_income"])

# tmap plot ---------------------------------------------------------------
tm_shape(new_nz) + tm_polygons("Median_income")
#> Warning: Current projection of shape new_nz unknown and cannot be
#> determined.
#> Warning: unknown projection
#> Legend labels were too wide. The labels have been resized to 0.26, 0.26, 0.26, 0.26, 0.26, 0.26. Increase legend.width (argument of tm_layout) to make the legend wider and therefore the labels larger.

# ggplot ------------------------------------------------------------------
ggplot() + geom_sf(data = new_nz, aes(fill = Median_income))

Created on 2018-11-25 by the reprex package (v0.2.1)

@Nowosad
Copy link
Contributor Author

Nowosad commented Nov 26, 2018

@edzer It looks good for me. Should I close the issue or there is still something related that needs to be tested?

@edzer edzer closed this as completed Nov 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants