# Converting points to multipoint with Z values in R

I have a dataset of POINTS with Z values and I would like to convert it to a MULTIPOINT dataset grouped by ID

I used the code from Converting points to polygons by group and it successfully grouped my points to multipoint but it dropped the z value.

Here is the code from the top answer of the other question which I based my own on:

``````set.seed(999)
xy = data.frame(x=runif(24), y=runif(24))
xy\$ID = rep(1:6, each = 4)

xys = st_as_sf(xy, coords=c("x","y"))

polys = xys %>%
dplyr::group_by(ID) %>%
dplyr::summarise() %>%
st_cast("POLYGON")

plot(polys)
``````

Here is what I actually used on my data

``````lsp_mp2 <- lsp %>%
dplyr::group_by(lsp\$ID) %>%
dply::summarise() %>%
st_cast('MULTIPOINT')
``````

How do I retain the Z value?

There is a column in my data with a Z value. The output of this function gave me an attribute table with only one column. All of the other columns were lost with this function.

Make a spatial sample data set with xyz geometry and an ID column:

``````d = data.frame(x=runif(20),y=runif(20),z=runif(20),id=sample(1:3,20,TRUE))
sd = st_as_sf(d, coords=1:3)
``````

split it by the ID:

``````sdsplit = split(sd, sd\$id)
``````

run st_combine on each element:

``````sdcombine = Map(st_combine, sdsplit)
``````

and join them all together:

``````sdset = do.call(c, sdcombine)
``````

giving MULTIPOINT geometries for the ID groupings with XYZ preserved

``````> sdset
Geometry set for 3 features
Geometry type: MULTIPOINT
Dimension:     XYZ
Bounding box:  xmin: 0.0440282 ymin: 0.03704024 xmax: 0.9970125 ymax: 0.9578563
z_range:       zmin: 0.3112239 zmax: 0.7384504
CRS:           NA
MULTIPOINT Z ((0.2610551 0.9356371 0.3112239), ...
MULTIPOINT Z ((0.7179385 0.3060261 0.0004098632...
MULTIPOINT Z ((0.8213335 0.3986064 0.8561131), ...
``````

And if you want that as a one-liner (and I'll use `Reduce` instead of `do.call` for no good reason):

``````sdset = Reduce(c, Map(st_combine,split(sd,sd\$id)))
``````

Only uses base packages and `sf`.

I believe you are looking for `sf::st_combine()` function, though the grouping muddles the waters somewhat.

For an ungrouped example consider this piece of code (note that the Z dimension works the best for points, while your sample code uses polygons; as a result I resort to my own favorite set of points - three semi-random cities in North Carolina, to make use of the wildly popular `nc.shp` shapefile).

Also note that the most typical use case of Z dimension is height; I am using population instead, as that is what I had the most easily available (see https://stackoverflow.com/questions/69796519/adjust-centroids-spatial-polygons-using-sf). It should have little effect on the output.

``````library(sf)
library(dplyr)

shape <- st_read(system.file("shape/nc.shp", package="sf")) # included with sf package

cities <- data.frame(name = c("Raleigh", "Greensboro", "Wilmington"),
x = c(-78.633333, -79.819444, -77.912222),
y = c(35.766667, 36.08, 34.223333),
population = c(467665, 299035, 115451)) %>%
st_as_sf(coords = c("x", "y", "population"), crs = 4326, dim = "XYZ")

result <- cities %>%
st_combine()

result
# Geometry set for 1 feature
# Geometry type: MULTIPOINT
# Dimension:     XYZ
# Bounding box:  xmin: -79.81944 ymin: 34.22333 xmax: -77.91222 ymax: 36.08
# z_range:       zmin: 115451 zmax: 467665
# Geodetic CRS:  WGS 84
# MULTIPOINT Z ((-78.63333 35.76667 467665), (-79...
``````