22 votos

Cómo convertir un spatialpolygon en un SpatialPolygonsDataFrame y añadir una columna a la tabla de atributos

coast<-readShapeSpatial("coastline.shp")
landc<-readShapeSpatial("landcover.shp")
ro<-readShapeSpatial("roads.shp")
bc<-gBuffer(ro,width=100)
landc$ratings=1
landc$ratings[landc$LANDUSE_ID==4]=0 

Arriba, cojo cualquier categoría que tenga 4 y en la nueva columna la pongo como 0.

En este punto, quiero que la columna llamada ratings también para el bc donde tomará 0 si está dentro del buffer y 1 si está fuera. El problema es que el bc es SpatialPolygons y no contiene la tabla de atributos.

Obviamente para añadir una columna a un SpatialPolygon hay que convertirlo en un objeto SpatialPolygonsDataFrame pero no sé cómo.

Probé esto:

buf_df<-as.data.frame(bc)
s_po<-SpatialPolygonsDataFrame(bc,buf_df)
s_po$ratings=0

pero aparece este error:

row.names of data and Polygons IDs do not match

15voto

Dan Puntos 16

¿Qué tienen que ver los objetos "coast", "ro" y "bc" con tu problema? El problema puede estar en que estás utilizando "readShapeSpatial". ¿Ha probado readOGR en rgdal? Si estás leyendo un shapefile de polígonos, readOGR resultará en un objeto SpatialPolygonsDataFrame.

Si, de hecho, tiene un objeto SpatialPolygons y quiere coaccionarlo en SpatialPolygonsDataFrame el dataframe especificado necesitará que sus rownames coincidan con los ID's de los polígonos en la ranura polygons. He aquí un ejemplo rápido.

library(sp)

# create some SpatialPolygons with ID's "2" and "3"
( p <- SpatialPolygons(list(Polygons(list(Polygon(cbind(c(2,4,4,1,2),c(2,3,5,4,2)))), "2"),
     Polygons(list(Polygon(cbind(c(5,4,2,5),c(2,3,2,2)))), "3"))) )
class(p)    

# Create a dataframe and display default rownames
( p.df <- data.frame( ID=1:length(p)) ) 
rownames(p.df)

# Try to coerce to SpatialPolygonsDataFrame (will throw error)
p <- SpatialPolygonsDataFrame(p, p.df) 

# Extract polygon ID's
( pid <- sapply(slot(p, "polygons"), function(x) slot(x, "ID")) )

# Create dataframe with correct rownames
( p.df <- data.frame( ID=1:length(p), row.names = pid) )    

# Try coersion again and check class
 p <- SpatialPolygonsDataFrame(p, p.df)
 class(p) 

# Now we can add a column
p@data$ratings <- 1:2 

# Or modify an existing one
p[p$ID < 2 ,] <- 5

10voto

Keith Puntos 1

Inténtalo:

#Code taken from the question:
s_po <- SpatialPolygonsDataFrame(bc, buf_df, match.ID = F) 

match.ID evita el requisito de rownames para match polygons ID

7voto

crstamps2 Puntos 233

Es muy sencillo:

library("rgdal")
polygons <- readOGR('path_to/file.shp',
                      layer = 'file')
class(polygons)
>[1] "SpatialPolygonsDataFrame"
>attr(,"package")
>[1] "sp"

poly_df <- as.data.frame(polygons)
# do some staff with "poly_df" that doesn't support SpatialPolygonsDataFrame
# then convert it to SPDF back again
s_poly <- SpatialPolygonsDataFrame(polygons, poly_df)
# add new column to SPDF:
s_poly$new_column <- "some data" 

Cuando el Error: "row.names of data and Polygons IDs do not match" surge esta solución parece ser útil: renombrar los IDs del marco de datos para que coincidan con los IDs de los polígonos:

newdata <- data.frame(whatever you want in here)
row.names(newdata) <- (however the new polygons are labeled)
polygons <- SpatialPolygonsDataFrame(polygons, newdata)

1voto

Paul jackson Puntos 11

Creo que la siguiente solución suele funcionar.

En primer lugar, cree un marco de datos vacío con ID como campo:

df <- data.frame(ID=character(), stringsAsFactors=FALSE )

A continuación, obtenga los ID de polígono espacial bc :

for (i in bc@polygons ) { df <- rbind(df, data.frame(ID=i@ID, stringsAsFactors=FALSE))  }
# and set rowname=ID
row.names(df) <- df$ID

A continuación, utilice df como segundo argumento de la función de conversión de marcos de datos espaciales:

spatial_df <- SpatialPolygonsDataFrame(bc, df)

En df y spatial_df son objetos de marco de datos, las columnas se pueden añadir fácilmente

0voto

Mark Webb Puntos 11

Utilicé esta solución de Roger B. https://stat.ethz.ch/pipermail/r-help/2005-December/085175.html

yourDF <- as.data.frame(yourPolygon)

set rowname=ID del polígono

row.names(yourDF) <- sapply(slot(yourPolygon, "polygons"), function(x) slot(x, "ID"))

A continuación, crea de nuevo su marco de datos espaciales con:

yourNewPolygon<- SpatialPolygonsDataFrame(yourPolygon, yourDF)

Pruebe cualquier operación en él como

yourNewPolygon<- elide(yourNewPolygon, rotate=-50)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X