1

I'm new to stars so hoping this is a simple answer and just me failing to understand the stars workflow properly.
R Version: 4.1.1
Stars Version: 0.5-5

library(stars)
library(starsdata) #install.packages("starsdata", repos = "http://gis-bigdata.uni-muenster.de", type = "source") 
#Create the rasters to read in as proxy
granule = system.file("sentinel/S2A_MSIL1C_20180220T105051_N0206_R051_T32ULE_20180221T134037.zip", package = "starsdata")
s2 = paste0("SENTINEL2_L1C:/vsizip/", granule, "/S2A_MSIL1C_20180220T105051_N0206_R051_T32ULE_20180221T134037.SAFE/MTD_MSIL1C.xml:10m:EPSG_32632")
r1<-read_stars(s2,,RasterIO=list(bands=1),proxy=T)
r2<-read_stars(s2,,RasterIO=list(bands=2),proxy=T)
r3<-read_stars(s2,,RasterIO=list(bands=3),proxy=T)
write_stars(r1,dsn="r1.tif")
write_stars(r2,dsn="r2.tif")
write_stars(r3,dsn="r3.tif")

Then I clear the objects from my environment and restart the R session.

#I clear all the objects and restart my R session here.
library(stars)
foo<-read_stars(c("r1.tif","r2.tif","r3.tif"),proxy=T)
r1<- foo[1]*0
r1[foo[1] > 4000 & foo[2] < 3000] <- 1
r1[foo[1] > 4000 & foo[2] >= 3000 & foo[2] <= 8000] <- 2  
r1[foo[1] > 4000 & foo[2] > 8000 & foo[3] < 2000] <- 4
r1[foo[1] > 4000 & foo[2] > 8000 & foo[3] >= 2000] <- 2
# plot(r1) #this works just fine if you run it
#why doesn't the below work?
write_stars(r1,dsn="out.tif")

Attempting to write out the file results in the following error:

Error in st_as_stars.list(mapply(fun, x, i, value = value, SIMPLIFY = FALSE),  : 
  !is.null(dx) is not TRUE

If instead of writing out the file, I plot the raster, it works just fine/as expected. Perhaps the issue is just my failure to understand that this answer applies to me too: How to reassign cell/pixel values in R stars objects

SIBeckers
  • 11
  • 4
  • 1
    Hi @SIBeckers, always difficult to help efficiently without a [minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). That said, I guess you should solve your problem with the following code: `write_stars(r1, dsn="out.tif")` – lovalery Dec 09 '21 at 23:56
  • Hey @lovalery, understood. Will try to update with some meaningful proxy rasters as example but it's definitely not just using the filename argument instead of dsn. Same error persists. – SIBeckers Dec 10 '21 at 01:19
  • Hi @SIBeckers. Thanks for your feedback. So, the problem may be related to your `r1`, `r2` and/or `r3` files because the rest of your code is good: on my side I managed to save the result of your code using the test image provided with the library (i.e. `L7_ETMS.tif`) and the line of code I gave you in my previous comment. – lovalery Dec 10 '21 at 14:29
  • Hi @lovalery, i think the example is reproducible now and i get the same error as I see with my own data. – SIBeckers Dec 10 '21 at 15:30

1 Answers1

0

First of all thank you for the effort you have made to make available a minimal reproducible example. Unfortunately the image you use is very heavy... and my pc is very old ! ;-) So I chose to use your example with another image (the test image of the stars library), easier to handle for my old computer.

So please find below a reprex which describes step by step the approach.

Reprex

  • STEP 1: Create three dummy stars proxy objects from the test image of the stars library
library(stars)

r <- system.file("tif/L7_ETMs.tif", package = "stars")

r1 <- read_stars(r, RasterIO = list(bands=1), proxy = TRUE)
r2 <- read_stars(r, RasterIO = list(bands=2), proxy = TRUE)
r3 <- read_stars(r, RasterIO = list(bands=3), proxy = TRUE)
  • STEP 2: Write every stars proxy object as .tif files on disk
write_stars(r1,dsn="r1.tif")
write_stars(r2,dsn="r2.tif")
write_stars(r3,dsn="r3.tif")
  • STEP 3: Merge r1, r2 and r3 in the stars proxy object foo
foo <- read_stars(c("r1.tif","r2.tif","r3.tif"), proxy = TRUE)

foo <- merge(foo)
  • STEP 4: Visualization of the foo stars proxy object
plot(foo)

If you want to display a specific band, proceed like this (here, showing band 3):

plot(foo[,,,3], main = st_dimensions(foo)["band"]$band$values[3])

  • STEP 5: Run your chunk of code
r1 <- foo[,,,3]*0 #0 create a proxy with 0s that we will replace using rules below
r1[foo[,,,1] > 40 & foo[,,,2] < 30] <- 1
r1[foo[,,,1] > 40 & foo[,,,2] >= 30 & foo[,,,2] <= 70] <- 2  
r1[foo[,,,1] > 40 & foo[,,,2] > 70 & foo[,,,3] < 7] <- 4
r1[foo[,,,1] > 40 & foo[,,,2] > 70 & foo[,,,3] >= 7] <- 2
  • STEP 6: Visualization of the output
plot(r1)

NB: I have deliberately not included the output raster here because at the end of the execution of your chunk of code, all pixels of the test image have the value 2. The output image is therefore a monochrome raster without any interest [this result is consistent with the pixel values of the original test image].

  • STEP 7: Save the output
write_stars(r1, dsn = "out.tif")
  • STEP 8: Checks that the file has been successfully written to the disk
file.exists("out.tif")
#> [1] TRUE

Created on 2021-12-10 by the reprex package (v2.0.1)

lovalery
  • 4,524
  • 3
  • 14
  • 28
  • Hi@SIBeckers, please find above a detailed answer. If it meets your needs please consider marking this answer as "accepted" and/or "upvoted". If not, please tell me what is still wrong. Cheers – lovalery Dec 10 '21 at 21:47
  • Hey @lovalery, thanks but some issues do exist. Step 5: r1 <- foo[3]*0 #0 create a proxy with 0s that we will replace using rules below Error in unclass(x)[[i]] : subscript out of bounds – SIBeckers Dec 13 '21 at 17:31
  • Hi @SIBeckers. I'm really sorry, I made a mistake when I copied and pasted. So I made the changes and it should work now. Please, let me know. – lovalery Dec 13 '21 at 18:34