Dimensions and extent changed after rast from ‘xyz’ data.frame

rrasterterra

s                                  #oringinal raster
s                                  #check dimensions and extent
df <- s %>% as.data.frame(xy=T)    #convert to df

t <- rast(df,type='xyz')           #convert to spatraster back
t                                  #check dimensions and extent

I have a oringinal raster called 's', and its nrows and ncols are 1510,1516.
But after I convert it to data.frame, and convert data.frame back to raster, its nrows and ncols are 1495, 1652.

Why it changed?

> s
class       : SpatRaster 
dimensions  : 1510, 1656, 1  (nrow, ncol, nlyr)
resolution  : 250, 250  (x, y)
extent      : 79018.05, 493018.1, 4079976, 4457476  (xmin, xmax, ymin, ymax)
coord. ref. : WGS 84 / UTM zone 49N (EPSG:32649) 
source      : memory 
name        :   sosslope 
min value   : -6.8730011 
max value   : -0.2319214 
> t
class       : SpatRaster 
dimensions  : 1495, 1652, 1  (nrow, ncol, nlyr)
resolution  : 250, 250  (x, y)
extent      : 79768.05, 492768.1, 4081976, 4455726  (xmin, xmax, ymin, ymax)
coord. ref. :  
source      : memory 
name        :   sosslope 
min value   : -6.8730011 
max value   : -0.2319214 

Best Answer

as.data.frame(xy=T) will remove cells that are NA. If you have outer rows or columns that are all NA, these will be trimmed off, resulting in a smaller raster on re-conversion. Use na.rm=FALSE in as.data.frame to return all points in the data frame.

Example, a small 3x4 raster of 1:12 values:

> s = rast(matrix(1:12,3,4))
> d = as.data.frame(s, xy=TRUE)

d is 12 rows as expected:

> dim(d)
[1] 12  3

convert to raster, get a 3x4 raster back:

> r = rast(d,type='xyz')
> dim(r)
[1] 3 4 1

Now try again with NA in the middle of the raster:

> s[2,2] = NA
> d = as.data.frame(s, xy=TRUE)

returns 11 points:

> dim(d)
[1] 11  3

but the resulting raster is still 3x4:

> r = rast(d,type='xyz')
> dim(r)
[1] 3 4 1

set the whole of the first column to NA:

> s[,1] = NA
> d = as.data.frame(s, xy=TRUE)
> r = rast(d,type='xyz')

And the result is now only 3x3:

> dim(r)
[1] 3 3 1

Use na.rm=FALSE (and you shouldn't use T and F for TRUE and FALSE):

> d = as.data.frame(s, xy=TRUE, na.rm=FALSE)
> dim(d)
[1] 12  3

That data frame retained the NA values, and they are included when reconstructing:

> r = rast(d,type='xyz')
> dim(r)
[1] 3 4 1

Giving back the original 3x4 raster.

I suspect this is what is happening with your data.

Related Question