Ben Lee
Ben Lee

Reputation: 35

Is it possible to create a stars object in R that is the minimum values of two other stars objects?

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?

Upvotes: 0

Views: 424

Answers (1)

lovalery
lovalery

Reputation: 4652

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)

Upvotes: 0

Related Questions