I've got some sf
objects I want to combine. I've stripped them down to a single polygon each (rtmp
and rtmp2
) for the purposes of this question. rbind()
and do.call(rbind,...)
seem to work fine, but bind_rows()
doesn't. Obviously I can work around this, but what am I missing?
(Data at bottom of question.)
These work:
library(dplyr) ## version 0.8.3
library(sf) ## version 0.8.0
r1 <- rbind(rtmp,rtmp2) ## works
r2 <- do.call(rbind,list(rtmp,rtmp2)) ## works
identical(r1,r2) ## TRUE
all.equal(r1,r2) ## fails??
Error: Can't join on 'geometry' x 'geometry' because of incompatible types (sfc_POLYGON/sfc / sfc_POLYGON/sfc)
This fails:
bind_rows(list(rtmp,rtmp2))
Error in .subset2(x, i) : attempt to select less than one element in get1index
In addition: Warning messages: 1: In bind_rows_(x, .id) : Vectorizing 'sfc_POLYGON' elements may not preserve their attributes 2: In bind_rows_(x, .id) : Vectorizing 'sfc_POLYGON' elements may not preserve their attributes
rtmp <- structure(list(PROVCODE = "ON", geometry = structure(list(structure(list(
structure(c(7201954.77714286, 7206422.6, 7206659.96857143,
7206183.55714286, 7206456.25714286, 7206918.87142857, 7207300.78857143,
7207337.03428571, 7207488.91714286, 7207400.89428571, 7208110.25714286,
7208360.52, 7208664.28571429, 7208710.88571429, 7208819.62285714,
7209207.96, 7209308.06285714, 7209665.33428571, 7209425.42857143,
7209568.68285714, 7209522.08285714, 7209870.72285714, 7210022.60571429,
7210017.42857143, 7210321.19428571, 7210507.59714286, 7210630.14,
7210407.49142857, 7210535.21142857, 7210378.15142857, 7210921.82285714,
7210906.87428571, 7211255.58285714, 7211310.45142857, 7211675.00857143,
7212183.14285714, 7208783.07714286, 7209760.22, 7208297.23714286,
7207629.9, 7201954.77714286, 935407.037142857, 937804.568571429,
937788.902857143, 937063.325714286, 936599.088571429, 936431.897142857,
936498.582857143, 936341.52, 936410.56, 936134.408571429,
936103.34, 935840.997142857, 935891.048571429, 935715.002857143,
935972.168571429, 936172.38, 935989.428571429, 935885.871428571,
935349.102857143, 935278.337142857, 934976.297142857, 934831.317142857,
934964.217142857, 934770.911428571, 934691.517142857, 934978.022857143,
934460.24, 934237.594285714, 933921.745714286, 933302.131428571,
933074.305714286, 932540.708571429, 932384.642857143, 931995.7,
932099.337142857, 931815.214285714, 929976.52, 928202.56,
927651.188571429, 927094.268571429, 935407.037142857), .Dim = c(41L,
2L))), class = c("XY", "POLYGON", "sfg"))), class = c("sfc_POLYGON",
"sfc"), precision = 0, bbox = structure(c(xmin = 7201954.77714286,
ymin = 927094.268571429, xmax = 7212183.14285714, ymax = 937804.568571429
), class = "bbox"), crs = structure(list(epsg = NA_integer_,
proj4string = NA_character_), class = "crs"), n_empty = 0L)), row.names = c(NA,
-1L), sf_column = "geometry", agr = structure(c(PROVCODE = NA_integer_), .Label = c("constant",
"aggregate", "identity"), class = "factor"), class = c("sf",
"tbl_df", "tbl", "data.frame"))
rtmp2 <- structure(list(PROVCODE = "ON", geometry = structure(list(structure(list(
structure(c(6914891.13617828, 7022510.44138576, 7130129.74659325,
7130129.74659325, 7022510.44138576, 6914891.13617828, 6914891.13617828,
896361.565655993, 958495.600487533, 896361.565655993, 772093.495992912,
709959.461161371, 772093.495992912, 896361.565655993), .Dim = c(7L,
2L), .Dimnames = list(NULL, c("x", "y")))), class = c("XY",
"POLYGON", "sfg"))), class = c("sfc_POLYGON", "sfc"), precision = 0, bbox = structure(c(xmin = 6914891.13617828,
ymin = 709959.461161371, xmax = 7130129.74659325, ymax = 958495.600487533
), class = "bbox"), crs = structure(list(epsg = NA_integer_,
proj4string = NA_character_), class = "crs"), n_empty = 0L)), row.names = 277L, class = c("sf",
"data.frame"), sf_column = "geometry", agr = structure(c(PROVCODE = NA_integer_), .Label = c("constant",
"aggregate", "identity"), class = "factor"))
rbind() throws an error whereas bind_rows assigns “NA” to those rows of columns missing in one of the data frames where the value is not provided by the data frames.
Syntax of the rbind() function rbind(): The rbind or the row bind function is used to bind or combine the multiple group of rows together.
We go back to initializing the output data frame with no rows and then adding the result of each turn of the loop as a new row in the output data frame. But when you now use bind_rows() rather than rbind() it runs much, much faster.
You can use the bind_rows() function from the dplyr package in R to bind together two data frames by their rows: bind_rows(df1, df2, df3, ...) Similarly, you can use the bind_cols() function from dplyr to bind together two data frames by their columns: bind_cols(df1, df2, df3, ...)
I had the same issue before and I figured out that rbindlist
does help to combine the list, but you have to convert it back to sf
object using st_as_sf()
this works for me:
p <- data.table::rbindlist(list(rtmp,rtmp2),
use.names = TRUE,
fill = TRUE,
idcol = NULL)
st_as_sf(p)
Simple feature collection with 2 features and 1 field
geometry type: POLYGON
dimension: XY
bbox: xmin: 7201955 ymin: 927094.3 xmax: 7212183 ymax: 937804.6
epsg (SRID): NA
proj4string: NA
PROVCODE geometry
1 ON POLYGON ((7201955 935407, 7...
2 ON POLYGON ((6914891 896361.6,...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With