0

I have two stars objects that are read in to R as tifs:

tif1 <- stars::read_stars("/data.tif")
tif2 <- stars::read_stars("/data2.tif")

They cover the same extent and have the same resolution. I know that I can do algebra with the objects -- for example, to create a new object that is the average of the values of the first two, I can use:

tif.avg <- (tif1 + tif2)/2

However, I want to know if it's possible to create a new object that extracts the minimum value from them instead. I've tried it a couple of different ways but I've hit a brick wall with this. Does anybody know if this is even possible?

Ben Lee
  • 35
  • 5
  • Please provide some additional details: each of the tif files has one or more bands? If they have multiple bands, is the "result" stars object you want for a particular band or for all bands? – lovalery Sep 20 '21 at 09:16
  • Hi @lovalery, each tif has only one band and the resulting object is therefore only for that band. – Ben Lee Sep 20 '21 at 13:05

1 Answers1

0

O.K. thanks for the clarification @Ben Lee. So, as a follow-up of your comment, please find below (cf. Reprex) one solution to your problem :

REPREX:

library(raster)
#> Le chargement a nécessité le package : sp
library(stars)
#> Le chargement a nécessité le package : abind
#> Le chargement a nécessité le package : sf
#> Linking to GEOS 3.9.1, GDAL 3.2.1, PROJ 7.2.1


# 1. Creating two stars objects
r1 <- raster(ncols = 3, nrows = 3)
values(r1) <- seq(length(r1))

r2 <- raster(ncols = 3, nrows = 3)
values(r2) <- rev(seq(length(r2)))

r_stack <- stack(r1, r2)
writeRaster(r_stack, "raster.tif", 
            bylayer = TRUE, suffix = 1:nlayers(r_stack))

tif1 <- read_stars("raster_1.tif")
tif2 <- read_stars("raster_2.tif")

# Array of the first stars object
tif1[[1]]
#>      [,1] [,2] [,3]
#> [1,]    1    4    7
#> [2,]    2    5    8
#> [3,]    3    6    9

# Array of the second stars object
tif2[[1]]
#>      [,1] [,2] [,3]
#> [1,]    9    6    3
#> [2,]    8    5    2
#> [3,]    7    4    1



# 2. Creating a 'stars' object with the minimum values
# of the two previous stars objects

# 2.1. retrieving the min values between the two stars object 
tif_min <- pmin(tif1[[1]], tif2[[1]])

# 2.2. converting the resulting array 'tif_min' into a stars object
tif_min <- st_as_stars(tif_min)

# 2.3. retrieving the dimensions from one of the two previous
# stars object (here, tif1) and setting a name
st_dimensions(tif_min) <- st_dimensions(tif1)
setNames(tif_min, "tif_min")

#> stars object with 2 dimensions and 1 attribute
#> attribute(s):
#>          Min. 1st Qu. Median     Mean 3rd Qu. Max.
#> tif_min     1       2      3 2.777778       4    5
#> dimension(s):
#>   from to offset delta refsys point values x/y
#> x    1  3   -180   120 WGS 84 FALSE   NULL [x]
#> y    1  3     90   -60 WGS 84 FALSE   NULL [y]

# 2.4 a little check!
tif_min[[1]]
#>      [,1] [,2] [,3]
#> [1,]    1    4    3
#> [2,]    2    5    2
#> [3,]    3    4    1
#>These are the minimum values of the two "star" input objects

Created on 2021-09-20 by the reprex package (v2.0.1)

Please confirm that this is what you were looking for (and if so, please do not forget to validate the answer to make it easier for other users to find this solution)

lovalery
  • 4,524
  • 3
  • 14
  • 28
  • Hi @Ben Lee, did my answer finally solve your problem? If so, please mark it as accepted to make it easier for other users to find the right answers. If you do not please write what the problem is. – lovalery Sep 22 '21 at 10:38
  • Hi @lovalery, this is exactly what I wanted! Thank you so much for your help! – Ben Lee Sep 23 '21 at 12:32
  • Hi @Ben Lee, Thank you for validating the answer and glad I could help you. I wish you all the best. – lovalery Sep 23 '21 at 12:47