2

I am new to the stars package in R, and am trying to work out how I assign new values to cells within a two dimensional stars object (a raster in raster package speak). With raster I can do as follows

> library("raster")
> library('stars')
> tif = system.file("tif/L7_ETMs.tif", package = "stars")
> ras<-brick(tif)[[2]] #create raster layer from 2nd layer of multilayer tif
> ras[1,1:5] #see first 5 values of top row of ras
[1] 56 57 52 45 52
> ras[1,1:4] <-100 #replace first 4 values of top row of ras
> ras[1,1:5]
[1] 100 100 100 100  52

According to the st_subset instructions in stars package manual, assignments follow ‘x[i]<-value’ but I am struggling to understand the use of ‘i’ in this context. My failed attempt is below, but I am hoping someone can provide a working alternative.

> tif = system.file("tif/L7_ETMs.tif", package = "stars")
> st<-read_stars(tif)[,,,2] #create raster layer from second layer of multilayer tif
> unlist(st[,1:5,1,]) #see first 5 values of top row of st
L7_ETMs.tif1 L7_ETMs.tif2 L7_ETMs.tif3 L7_ETMs.tif4 L7_ETMs.tif5 
          56           57           52           45           52 
> st[,1:4,1,]<-100 #replace first 4 values of top row of ras
Error in `[<-.stars`(`*tmp*`, , 1:4, 1, , value = 100) : 
  unused arguments (alist(1:4, 1, ))

Many thanks

Terry B
  • 83
  • 7

1 Answers1

5

The stars values can be accessed and modified through the underlying matrix (if single band) or array (if multi-band), accessed with r[[1]].

For example:

library(stars)

# Reading 2nd band
tif = system.file("tif/L7_ETMs.tif", package = "stars")
r = read_stars(tif, RasterIO = list(bands = 2))

# Accessing values (as matrix)
r[[1]][20:140,20:30]

    ##        [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
    ##   [1,]   65   66   67   64   61   59   56   39   40    40    40
    ##   [2,]   62   56   52   48   44   42   38   41   40    40    40
    ##   [3,]   50   44   41   40   40   39   40   41   43    42    41
    ##   ...

# Modifying values
r[[1]][20:140,20:30] = 100

# Plot
plot(r)

plot

Michael Dorman
  • 950
  • 6
  • 8
  • 1
    By the way, I know it wasn't my question, but your code doesn't work for stars proxy objects. I'm pretty sure this is because proxy object values aren't read into memory? Are you able to suggest how to perform similar operations on a stars proxy object if the original raster is too large to read into memory? – Terry B Mar 03 '21 at 13:17
  • 1
    You're right, with `stars_proxy` the matrix/array of values can't be accessed that way. In that case, I'd suggest "burning" a polygon with an attribute (which you can set to any value in advance) into the raster, using either `st_rasterize` which works on `stars_proxy` or even with `gdal_rasterize` on the command line without using R at all. If you need to position the polygon according to specific raster rows and columns, then you can read the relevant subset (https://cran.r-project.org/web/packages/stars/vignettes/stars2.html#reading-a-particular-chunk) and then convert with `st_as_sf`. – Michael Dorman Mar 03 '21 at 13:53