1

I want to save a numerical matrix and then restore it accurately. But if I use identical() to compare the before- and after-saved matrices, they are not identical. I guess the problem is caused by floating point precision issues. How can I make the two matrices identical?

Thanks!

options(digits = 10)

data <-
  c(1 / 11, 1 / 22, 1 / 33, 1 / 44, 1 / 55, 1 / 66, 1 / 77, 1 / 88, 1 / 99) # Generate a numerical matrix.

x <- matrix(data,
            nrow = 3,
            ncol = 3,
            byrow = TRUE)

write.table(x, "test.csv") # Save the matrix.

y <- as.matrix(read.table("test.csv")) # Restore the matrix.

y <- unname(y) # Remove the attributes.

all.equal(x, y) # I got TRUE.

identical(x, y) # I got FALSE. How can I get TRUE here?

unlink("test.csv")
Frank KKK
  • 313
  • 1
  • 2
  • 6
  • `all.equal` and `identical` are different things: `all.equal` tests for near equality, while `identical` is more exact (e.g. it has no tolerance for differences, and it compares storage type). See here – TarJae Oct 07 '22 at 19:15
  • 1
    You will also lose precision when “printing” to csv. What do you see if you save with `saveRDS` and load with `readRDS`? – Limey Oct 07 '22 at 19:19
  • Wow. saveRDS() and readRDS() save me! I love them. Thanks. – Frank KKK Oct 07 '22 at 19:28

1 Answers1

0

all.equal has a tolerance parameter whose default allows for the values being compared to be very near equal but not exactly so while identical requires exact equality.

If you'd like the restored file to be identical, you can save as an RDS rather than a csv. Saving as an RDS also preserved other attributes of an R object that saving as a csv does not, allowing you to avoid converting the object back to the desired type after read in.

options(digits = 10)

data <-
  c(1 / 11, 1 / 22, 1 / 33, 1 / 44, 1 / 55, 1 / 66, 1 / 77, 1 / 88, 1 / 99) # Generate a numerical matrix.

x <- matrix(data,
            nrow = 3,
            ncol = 3,
            byrow = TRUE)

saveRDS(x, "test.RDS")

y <- readRDS( "test.RDS") # Restore the matrix.

all.equal(x, y) 
#> [1] TRUE

identical(x, y) 
#> [1] TRUE

unlink("test.RDS")
Austin Graves
  • 1,044
  • 5
  • 12
  • 1
    Thanks. I found the saved RDS file reduces my original 4GB csv file (a huge matrix) to only 1GB. This is so nice, in terms of disk space! – Frank KKK Oct 07 '22 at 19:33