Skip to content

raster::clump not working?

7 messages · João Carreiras, Ben Tupper, Bede-Fazekas Ákos +2 more

#
Hi!

I've been trying to run the clump command but the output is consistently a
raster with values == 1. Please find below an example.

I'm sure I'm doing something stupid. However, the command is really
straightforward and I can't seem to identify what the problem might be.

Any help really appreciated.
Thanks
Joao

r <- raster(ncols=36, nrows=18)
x <- init(r, fun='cell')
x
class       : RasterLayer
dimensions  : 18, 36, 648  (nrow, ncol, ncell)
resolution  : 10, 10  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names       : layer
values      : 1, 648  (min, max)
a <- clump(x)
a
class       : RasterLayer
dimensions  : 18, 36, 648  (nrow, ncol, ncell)
resolution  : 10, 10  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
data source : in memory
names       : clumps
values      : 1, 1  (min, max)
#
Hi,

I think it is actually correct - there is only one 'clump' of connected cells.  In raster clumps are separated from other clumps by backgound (0 or NA).  In your example there is no background anywhere so there is just one clump. 

You can see the difference if you divide x in to halves with a row of NAs.  Note that limited spatial extent so the clumping doesn't wrap around the globe which it will for [-180, 180].

r <- raster(ncols=36, nrows=18, xmn = 0, xmx = 36, ymn = 0, ymx = 18)
x <- init(r, fun='cell')
 
x[9,1:36] <- NA
y <- clump(x)
y
# class       : RasterLayer 
# dimensions  : 18, 36, 648  (nrow, ncol, ncell)
# resolution  : 1, 1  (x, y)
# extent      : 0, 36, 0, 18  (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
# data source : in memory
# names       : clumps 
# values      : 1, 2  (min, max)

x[1:18, 18] <- NA
y
# class       : RasterLayer 
# dimensions  : 18, 36, 648  (nrow, ncol, ncell)
# resolution  : 1, 1  (x, y)
# extent      : 0, 36, 0, 18  (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
# data source : in memory
# names       : clumps 
# values      : 1, 4  (min, max)


Cheers,
Ben
Ben Tupper
Bigelow Laboratory for Ocean Sciences
60 Bigelow Drive, P.O. Box 380
East Boothbay, Maine 04544
http://www.bigelow.org

Ecological Forecasting: https://eco.bigelow.org/
#
Dear Joao,
I think function clump() works as it should be. A toy example:
x <- raster(matrix(sample(x = c(NA, NA, NA, 1), size = 36*18, replace = 
TRUE), ncol=36, nrow=18))
plot(x)
plot(clump(x))

Maybe you are searching for a function that aggregate those cells that 
have the same value?
In this case it would do what you want (I'm sure there is a more 
straightforward way...):
r <- raster(ncols=36, nrows=18)
x <- init(r, fun='cell')
y <- layerize(x)
ids <- calc(x = y, fun = function(layers) 
{return(which(as.logical(layers))[1])})
plot(ids)

HTH,
?kos Bede-Fazekas
Hungarian Academy of Sciences


2018.05.25. 12:00 keltez?ssel, Jo?o Carreiras ?rta:
#
Dear Ben,

Thank you for your prompt reply.

Now I see what clump does. I just thought clump would give the same
result as ArcGIS "Region Group". I need some command to assign a
different value to each patch. And by patch I mean contiguous pixels
having the same value, so that in this (absurd) example I would get
648 patches.

Take care
Joao
On 25 May 2018 at 11:35, Ben Tupper <btupper at bigelow.org> wrote:
#
Joao, this is what you are after I think.  It's important to use
sf/fasterize otherwise any holes filled by other patches won't be
identified (and it's faster). It won't scale well given rasterToPolygons,
but there might be other options using sf related tricks.

library(raster)
r <- raster(volcano) %/% 20
## p has six distinct values (multipolygons)
p <- rasterToPolygons(r, dissolve = TRUE)
## pp has ten distinct patches
pp <- disaggregate(p)
pp$patch <- seq_len(nrow(pp))

## back to raster
#rr <- rasterize(pp, r, field = pp$patch)
# or faster with sf/fasterize (also this gets the holes filled correctly)
rr <- fasterize::fasterize(sf::st_as_sf(pp), r, field = "patch")
unique(values(rr))

Cheers, Mike.
On Fri, 25 May 2018 at 21:15 Jo?o Carreiras <jmbcarreiras at gmail.com> wrote:

            
#
Check out SDMTools::ConnCompLabel
I think that will get you what you're after.

Hope that helps!
Mike


Please pardon any typos, this message was sent from a mobile device.
On Fri, May 25, 2018, 7:15 AM Jo?o Carreiras <jmbcarreiras at gmail.com> wrote:

            

  
  
#
Dear Mike,

great and many thanks as this is exactly what I was after.

Cheers
Joao
On 25 May 2018 at 12:58, Michael Sumner <mdsumner at gmail.com> wrote: