I would need help with raster stack.
I have a 365-layers raster stack (corresponding to an hydrological year) and I want to substitute the pixel with value 3 with the value of the last previous layer with different value.
For example, for a specific pixel I have the first 10 layers that give values:
1,1,2,3,3,3,3,2,1,1.
The layers where the value is 3 should be substituted with, in this case, 2, which is the last value, before the "3-window", different from 3.
This should be done for all layers (except, obviously, the first one) for each pixel.
Any idea?
I just convert my raster in a matrix and I work with matrices but this requires a lot of time.
Let's suppose that vel_3D_snow_P4 is my matrix (retrieved from raster) where I have 365 rows (days) and more than 400000 columns (pixels), I writed this code:
vel_3D_snow_P4_back=matrix(nrow=nrow(vel_3D_snow_P4),ncol=ncol(vel_3D_snow_P4))
for (i in 1:ncol(vel_3D_snow_P4)){
y <- which(vel_3D_snow_P4[,i]==3)
startIndex <- y[!(y-1) %in% y]
stopIndex <- y[!(y+1) %in% y]
matrix=matrix(nrow=length(startIndex),ncol=2)
matrix[,1]=startIndex
matrix[,2]=stopIndex
new_vector_back=vel_3D_snow_P4[,i]
for (j in 1:nrow(matrix)){
if (matrix[j,1]==1) next
new_vector_back[matrix[j,1]:matrix[j,2]]=new_vector_back[matrix[j,1]-1]
}
vel_3D_snow_P4_back=cbind(vel_3D_snow_P4_back,new_vector_back)
print(c("fine",toString(i)))
}
But, as you can imagine, with numerous pixels it is impossible! This is the reason why I was asking for a solution/idea by maintaining raster format (maybe using calc function?)
Thanks in advance.
Typically, the first step with problems like this is in R, is to write a function that operates on a vector. Or search for an existing one. My first google query pointed me to zoo::na.locf
library(zoo)
x <- c(1,1,2,3,3,3,3,2,1,1)
x[x==3] <- NA
na.locf(x)
# [1] 1 1 2 2 2 2 2 2 1 1
Then create example raster data
library(raster)
r <- raster(ncol=10, nrow=10)
s <- stack(lapply(c(1,2,3,3,4), function(i) setValues(r, i)))
And combine the two. You can do
A)
x <- reclassify(s, cbind(3, NA))
z <- calc(x, fun=na.locf)
or
B)
f <- function(v) {
v[v==3] <- NA
na.locf(v)
}
zz <- calc(s, f)
Related
I have two raster files (values ranges from 0 to 1) and I want to find the difference between them. But the problem is there are certain values those are missing. So I want to assign them value 1 (Like NA=1). How can I do this? Any expert can solve this little query. Thanks
My code is this.
library(raster)
R1 <- raster ("D:/Results/1.tiff")
R2 <- raster ("D:/Results/2.tiff")
Se1= R2-R1
plot(Se1)
How large is your raster files and how limited by memory are you? With raster, the optimal memory safe approach when interacting with large files is to use the reclassify function shown below. Let me know if it works.
# Package names
library(raster)
# Read in files
R1 <- raster("D:/Results/1.tiff")
R2 <- raster("D:/Results/1.tiff")
# use the reclassify function to group values to other values.
# In this case, NA values to 1.Reclassification is done with matrix rcl ,
# in the row order of the reclassify table.
D1 <- reclassify(R1, cbind(NA, 1))
D2 <- reclassify(R2, cbind(NA, 1))
# Find the difference between the two and plot.
Se1 = R2-R1
plot(Se1)
Here is how you may do that with "terra" (the replacement of "raster")
library(terra)
R <- rast(paste0("D:/Results/", 1:2, ".tiff"))
R <- subst(R, NA, 1)
Se1 <- diff(R)
I need to create some new rasters by assigning values using z <- rast(x, vals = y). I would like the new raster (z) to have NA values at the same location as the old raster (x), but with the newly assigned value(s) (y) in the non-NA cells.
What is the most efficient way to create a new raster with a matching NA pixels but with new values assigned to the non-NA pixels?
I don't see any argument to handle NA values listed in the documentation for rast(), so do I need to do a two step process where the value is first assigned to all cells and then NAs are transfered from the old raster to new?
In the following example I would like s to have the same outline as r but have a uniform value of 10 in the non-NA cells.
f <- system.file("ex/elev.tif", package="terra")
r <- rast(f)
s <- rast(r, vals=10) # This fill all rasters cells, including NAs
Here are four ways to do that:
library(terra)
f <- system.file("ex/elev.tif", package="terra")
r <- rast(f)
s1 <- classify(r, cbind(-Inf, Inf, 10))
s2 <- init(r, 10) |> mask(r)
s3 <- ifel(is.na(r), NA, 10)
s4 <- r * 0 + 10
I would expect approach 1 and 4 to be the most efficient.
I want to analyze a raster stack and determine the first layer in the stack that meets a condition for every pixel.
# Generate stack of random values
library(raster)
r1 <- r2 <- r3 <- r4 <-r5 <- r6 <- r7 <- raster(ncol=10, nrow=10)
r1[] <- rpois(ncell(r1), 1)
r2[] <- rpois(ncell(r2), 1)
r3[] <- rpois(ncell(r3), 1)
r4[] <- rpois(ncell(r4), 1)
r5[] <- rpois(ncell(r5), 1)
r6[] <- rpois(ncell(r6), 1)
r7[] <- rpois(ncell(r7), 1)
# stack them
s <- stack(r1,r2,r3,r4,r5,r6,r7)
I want to take this stack and determine the first layer to meet a condition like: "Value = 1 for 3 consecutive layers" or "2 of last 3 layers have value = 1", for example.
Can you think of any function to do this?
If I run rasterToPoints I can convert the stack into a dataframe with columns representing each layer value. This may make things easier.
values<-as.data.frame(rasterToPoints(s))
values<-values[,3:ncol(values)] #eliminates two columns at the beginning
values$first<-NA
At this point I think I would want to loop through and fill in the values$first column with the first column meeting my condition.
Once I determine the correct layer for each pixel, I then want an output raster with that correct layer number as the value for each pixel.
I'd appreciate any help!
Somewhat similar question posted here, though that's counting the number of layers that meet a condition.
You can write a function that can do this for a vector and then use it in raster::calc.
For example, to find the first layer that has a value of 3
f <- function(x) which(x == 3)[1]
(and handles the case that none of the values is 3 well, by returning NA)
For example
library(raster)
s <- stack(system.file("external/rlogo.grd", package="raster"))
f <- function(x) which(x == 255)[1]
x <- calc(s, f)
plot(x)
I am trying to use raster::focal to find out how many neighbors of value 1 each raster cell has. However, I have noticed that in the resulting raster the edge cells have been replaced with NA values. How can I get neighbor counts for the outer edge of the raster?
Here is a reproducible example:
#create raster and add 1's and 0's
land <- raster(matrix(0, 8, 10), xmn=408027.5, xmx=413027.5, ymn=4370000,
ymx=4374000)
land[4:8, 2:5] <- 1
land[2:3, 8:9] <- 1
land[1,0:10] <- 1
land[is.na(land[])] <- 0
#plot the raster
plot(land)
#create window for focal function
w <- matrix(1,3,3)
#run raster::focal
land.foc <- focal(land, w=w, fun=sum)
#plot resulting focal raster
plot(land.foc)
#plot NA values in land.foc
plot(is.na(land.foc))
However, as you can see when you compare the two rasters, the outer-most cells in the focal raster have been replaced with NA's.
You just need to set pad=TRUE and padValue=0. This 'extends' your raster and adds virtual rows and columns with you padValue, in this case 0.
land.foc <- focal(land, w=w, fun=sum,pad=T,padValue=0)
plot(land.foc)
plot(is.na(land.foc))
Edit:
Another way of looking at it is that the virtual cells don't have any values, they are NA.
So instead of assigning 0 as padValue, just add na.rm=TRUE to your call.
If you really need to do something else with the virtual cells, you can create your own function, which handles the NA cells more specific, that you then pass into focal.
I am trying to determine the location of raster cells that add up to a given amount, starting with the maximum value and progressing down.
Eg, my raster of 150,000 cells has a total sum value of 52,000,000;
raster1 <- raster("myvalues.asc")
cellStats(raster1,sum) = 52,000,000
I can extract the cells above the 95th percentile;
q95 <- raster1
q95[q95 < quantile(q95,0.95)] <- NA
cellStats(q95,sum) = 14,132,000
as you can see, the top 5% cells (based upon quantile maths) returns around 14 million of the original total of 'raster1'.
What i want to do is predetermine the overall sum as 10,000,000 (or x) and then cumulatively sum raster cells, starting with the maximum value and working down, until I have (and can plot) all cells that sum up to x.
I have attempted to convert 'raster1' to a vector, sort, cumulative sum etc but can't tie it back to the raster. Any help here much appreciated
S
The below is your own answer, but rewritten such that it is more useful to others (self contained). I have also changed the %in% to < which should be much more efficient.
library(raster)
r <- raster(nr=100, nc=100)
r[] = sample(ncell(r))
rs <- sort(as.vector(r), decreasing=TRUE)
r_10m <- min( rs[cumsum(rs) < 10000000] )
test <- r
test[test < r_10m ] <- NA
cellStats(test, sum)
couldnt find the edit button.....
this is something like what i need, after an hour scratching my head;
raster1v <- as.vector(raster1)
raster1vdesc <- sort(raster1v, decreasing=T)
raster1_10m <- raster1vdesc[cumsum(raster1vdesc)<10000000]
test <- raster1
test[!test%in%raster1_10m] <- NA
plot(test)
cellStats(test,sum) = 9,968,073
seems to work, perhaps, i dunno. Anything more elegant would be ideal