5

When doing raster math, for example raster1-raster2, the datatype of the output raster is 'FLT4S', even if the datatype ot both raster1 and raster 2 is 'INT2S'. How can I force the output to be 'INT2S', without writing to disk? Is there a global way of doing it saying that all raster processing shall result in INT2S data?

The reason for wanting 'INT2S' instead of 'FLT4S' is to save memory space and speed up processing when using for loops on larger raster datasets.

In rasterOptions() one can specify dataType, but as far as I understand that only applies when writing to disk, right?

#load package raster
require (raster)

#create sample rasters
r1<-raster::raster(ext=extent(c(0,10,0,10)), res=1, vals=1:100)
r2<-raster::raster(ext=extent(c(0,10,0,10)), res=1, vals=100:1)

#set dataType of sample rasters to 'INT2S'
dataType(r1)<-'INT2S'
dataType(r2)<-'INT2S'

#check dataType of sample rasters
dataType(r1)
dataType(r2)

#do some simple arithmetics
r3<-r2-r1

#check the dataType of the output raster
dataType(r3)

I would like dataType(r3) to be 'INT2S' as well

Kristin
  • 51
  • 3

4 Answers4

1

In your example, it actually does work. Notice the L after the numbers if the vals argument. That is equivalent to as.integer

library(raster)
r1 <-raster::raster(ext=extent(c(0,10,0,10)), res=1, vals=1:100L)
r2 <-raster::raster(ext=extent(c(0,10,0,10)), res=1, vals=100:1L)

r3 <- r2 - r1
class(values(r3))
#[1] "integer"

But in other cases it does not work

class(values(r3 - 2L))
[1] "numeric"

And you cannot control that behavior.

Note that dataType provides information about the file that the RasterLayer refers to. If there is no file, like in the above example, the value is meaningless. You should also not set it, except for debugging when dealing with an existing file.

So the best you can do is set the datatype when writing to disk as in

writeRaster(r3, filename="test.tif", datatype="INT2S")
Robert Hijmans
  • 40,301
  • 4
  • 55
  • 63
0

I have the same problem with 'INT2U' data and I don't believe it's possible. AFAIK, R supports 'numeric'. Floating point can be coerced to 'integer' with 'as.integer()' but I think it's just truncated.

Nate Lockwood
  • 3,325
  • 6
  • 28
  • 34
0

I've had this same question too. Hopefully someone will chime in if I'm wrong, but I believe you really only have one option and that is to convert the output when you write to disk:

writeRaster(r3,filename="r3.tif", format="GTiff", datatype='INT2S')

then load back into R.

You can convert the output after the calculation, but it does not change the size of the object:

dataType(r3)<-'INT2S'

You can check the object size using:

object.size(r3)

If you write the data to disk and reload the object size will be smaller.

Tim Assal
  • 677
  • 6
  • 15
0

Another option is to use the calc or overlay functions in raster to do some math, save to disk and return the resulting raster in one go. I wrote the example rasters to disk to start since Robert said you should not assign it and in real cases you will probably be reading from disk.

# load package raster
library(raster)

# create sample rasters on disk
r1 <- raster::raster(ext = extent(c(0, 10, 0, 10)), res = 1, vals = 1:100)
r2 <- raster::raster(ext = extent(c(0, 10, 0, 10)), res = 1, vals = 100:1)

r1_fl <- tempfile(fileext = ".tif")
r2_fl <- tempfile(fileext = ".tif")
r3_fl <- tempfile(fileext = ".tif")

writeRaster(r1, r1_fl, datatype = "INT2S")
writeRaster(r2, r2_fl, datatype = "INT2S")

# read rasters from disk
r1 <- raster(r1_fl)
r2 <- raster(r2_fl)

# check dataType of sample rasters
dataType(r1)
dataType(r2)

# do some simple (or complex) arithmetic
r3 <- overlay(r1, r2, fun = function(x, y){x - y}, filename = r3_fl,
  datatype = "INT2S")

# check the dataType of the output raster
dataType(r3)
see24
  • 1,097
  • 10
  • 21