2017-03-16 5 views
3

Ich habe ein sf Objekt von POLYGON Geometrie-Typ. Ich möchte diese Polygone in MULTIPOLYGONs mit dem Gruppierungsattribut (group_attr) aggregieren und ein neues MULTIPOLYGON-Objekt mit einer Attributtabelle verbinden. Als Ergebnis werde ich ein Objekt mit zwei Zeilen und drei Spalten (group_attr, second_attr, geometry) haben. Ich habe bereits versucht, st_cast zu verwenden - es funktioniert gut auf sfc Objekte, aber nicht auf sf Objekte. Ist es möglich, dies mit sf Paket zu tun?Aggregieren POLYGONS zu MULTIPOLYGONs und halten data.frame

p1 <- rbind(c(0,0), c(1,0), c(3,2), c(2,4), c(1,4), c(0,0)) 
pol1 <-st_polygon(list(p1)) 
p2 <- rbind(c(3,0), c(4,0), c(4,1), c(3,1), c(3,0)) 
pol2 <-st_polygon(list(p2)) 
p3 <- rbind(c(4,0), c(4,1), c(5,1), c(5,0),c(4,0)) 
pol3 <-st_polygon(list(p3)) 
p4 <- rbind(c(3,3), c(4,2), c(4,3), c(3,3)) 
pol4 <-st_polygon(list(p4)) 

d <- data.frame(group_attr = c(1, 1, 2, 2), 
       second_attr = c('forest', 'forest', 'lake', 'lake')) 
d$geometry <- st_sfc(pol1, pol2, pol3, pol4) 
df<- st_as_sf(d) 
plot(df) 
df 

Simple feature collection with 4 features and 2 fields 
geometry type: POLYGON 
dimension:  XY 
bbox:   xmin: 0 ymin: 0 xmax: 5 ymax: 4 
epsg (SRID): NA 
proj4string: NA 
    group_attr second_attr      geometry 
1   1  forest POLYGON((0 0, 1 0, 3 2, 2 4... 
2   1  forest POLYGON((3 0, 4 0, 4 1, 3 1... 
3   2  lake POLYGON((4 0, 4 1, 5 1, 5 0... 
4   2  lake POLYGON((3 3, 4 2, 4 3, 3 3)) 

enter image description here

Antwort

1

Ein neuer Ansatz basiert auf https://github.com/r-spatial/sf/issues/634#issuecomment-365151794:

library(dplyr) 

df_new <- df %>% 
    group_by(group_attr) %>% 
    summarise_all(first) 
df_new 

Simple feature collection with 2 features and 2 fields 
geometry type: MULTIPOLYGON 
dimension:  XY 
bbox:   xmin: 0 ymin: 0 xmax: 5 ymax: 4 
epsg (SRID): NA 
proj4string: NA 
# A tibble: 2 x 3 
    group_attr second_attr              geometry 
     <dbl> <fct>              <MULTIPOLYGON> 
1  1.00 forest  (((3 0, 3 1, 4 1, 4 0, 3 0)), ((0 0, 1 4, 2 4, 3 2, 1 0, 0 0))) 
2  2.00 lake     (((4 0, 4 1, 5 1, 5 0, 4 0)), ((3 3, 4 2, 4 3, 3 3))) 
0

Sehr Hacky (oder naive) Ansatz:

attr_table <- df %>% 
     as_data_frame() %>% 
     select(-geometry) %>% 
     unique() 

new_df <- df %>% 
     group_by(group_attr) %>% 
     summarise() %>% 
     as.data.frame(.) %>% 
     left_join(., attr_table, by='group_attr') %>% 
     st_as_sf() 

new_df 

Simple feature collection with 2 features and 2 fields 
geometry type: MULTIPOLYGON 
dimension:  XY 
bbox:   xmin: 0 ymin: 0 xmax: 5 ymax: 4 
epsg (SRID): NA 
proj4string: NA 
    group_attr second_attr      geometry 
1   1  forest MULTIPOLYGON(((3 0, 3 1, 4 ... 
2   2  lake MULTIPOLYGON(((4 0, 4 1, 5 ... 
2

oder:

> aggregate(df, list(df$second_attr), function(x) x[1]) 
Simple feature collection with 2 features and 3 fields 
Attribute-geometry relationship: 0 constant, 2 aggregate, 1 identity 
geometry type: MULTIPOLYGON 
dimension:  XY 
bbox:   xmin: 0 ymin: 0 xmax: 5 ymax: 4 
epsg (SRID): NA 
proj4string: NA 
    Group.1 group_attr second_attr      geometry 
1 forest   1  forest MULTIPOLYGON(((3 0, 3 1, 4 ... 
2 lake   2  lake MULTIPOLYGON(((4 0, 4 1, 5 ... 
+0

Danke - das funktioniert sauber. Ich werde feststellen, dass ich eine kleine Variation dieses 'emp <- st_is_empty (df) verwenden musste; Aggregat (df [! emp,], by = Liste (df $ second_attr [! emp]), FUN = Funktion (x) x [1]) 'weil ich einige leere Polygone hatte. Nach viel Haarriss habe ich herausgefunden, dass ich sie zuerst ausschließen musste. – thelatemail

+0

Wenn du glaubst, dass dies ein Problem ist, erhöhe es bitte als Problem auf der sf github-Seite. –

Verwandte Themen