I downloaded a map in TIF format that came with the following files: a2_LOt_12.tif.vat.cpg; a2_LOt_12_v170321.tfw; a2_LOt_12_v170321.tif; a2_LOt_12_v170321.tif.aux; a2_LOt_12_v170321.tif.ovr a2_LOt_12_v170321.tif.vat.dbf; a2_LOt_12_v170321.tif (XML doc). In ArcGIS the file opens fine and I can access the attribute table: enter image description here However, I am having a tough time opening that table in R. I expected "levels()" to work, but it returns "NULL":

r <- raster("a2_LOt_12_v170321.tif")

Is there another way to access that attribute table in R?

  • The value attribute table (VAT) of ArcGIS is not usually a standard part of raster models. Since the dBase-III+ file exists in your data sample (as .tif.vat.dbf), you can likely find some way of opening it, but treating it as a natural part of the raster might not be the best process.
    – Vince
    Commented Mar 2, 2018 at 22:07

1 Answer 1


Per the raster documentation, adding 'RAT = TRUE' when reading in the file should solve your problem, so long as the .tif.aux.xml file holds category data. Demo:

options(stringsAsFactors = FALSE)

test <- raster(nrows = 10, ncols = 10)
test[] <- sample(1:10, 100, replace = TRUE)

test_rat <- data.frame('ID' = seq.int(10),
                       'CAT' = c('cat', 'dog', 'banana', 'ship', 'egg',
                                 'tree', 'beer', 'shoe', 'light', 'pen'))

levels(test) <- test_rat

writeRaster(test, 'C:/data/test_rat.tif', datatype = 'INT2S', overwrite = TRUE)

tested <- raster('C:/data/test_rat.tif', RAT = TRUE)

# optional:               

The tif.aux.xml generated by writeRaster above looks like:

  <PAMRasterBand band="1">

so if your file looks similar you should be fine.


If the attribute data is in a dbf, try something like this:

# read the tif in with RAT = TRUE. Should get an ID column at least in the resulting object.
data_tif <- raster(file.path(getwd(), 'a2_LOt_12_v170321.tif', RAT = TRUE)

# read the dbf in as a data frame
data_dbf <- foreign::read.dbf(file.path(getwd(), 'a2_LOt_12_v170321.tif.vat.dbf'))

Have a look at levels(data_tif)[[1]] and compare with data_dbf. Make sure number of rows matches, and look for columns in common (ID in the RAT may match VALUE in the dbf, for instance). You can then use base::merge or dplyr::left_join to append the dbf data to the RAT.

Note that write support for RATs is minimal - some advice is here: https://stackoverflow.com/questions/23840178/how-to-write-a-raster-with-rat-factors-in-r-raster-package

Thanks to this question for providing some data I could test with.

  • Thanks. That did not work for my case, but someone suggested me to read the attribute table individually using the package "foreign" as in: rat <- read.dbf("a2_LOt_12_v170321.tif.vat.dbf")
    – TWest
    Commented Mar 5, 2018 at 14:59
  • And then add that to the raster file. It worked for what I wanted to do.
    – TWest
    Commented Mar 5, 2018 at 15:01
  • Yes, I added that method in an edit yesterday. Glad it worked for you.
    – obrl_soil
    Commented Mar 5, 2018 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.