Skip to content

Instantly share code, notes, and snippets.

@JosiahParry
Last active November 28, 2024 18:44
Show Gist options
  • Save JosiahParry/9b00ef1465814ec540752b95fde95434 to your computer and use it in GitHub Desktop.
Save JosiahParry/9b00ef1465814ec540752b95fde95434 to your computer and use it in GitHub Desktop.
focal mean using base R is faster than using terra
library(terra)
library(Matrix)
# create a sample raster
r <- rast(ncols=10, nrows=10, ext(0, 10, 0, 10))
x <- 1:ncell(r)
values(r) <- x
# why is there NaN in here????
adj_raw <- adjacent(r, 1:ncell(r), "queen")
# create a sparse matrix in a ragged array
adj_list <- vector("list", nrow(adj_raw))
for (i in seq_len(nrow(adj_raw))) {
adj_list[[i]] <- c(i, filter_row(adj_raw[i,]))
}
# prepare to create the sparse matrix
i <- rep.int(x, lengths(adj_list))
j <- unlist(adj_list)
w <- rep(1, length(i))
# create the sparse matrix
mr <- sparseMatrix(
i, j, x = w, repr = "R",
) |> forceSymmetric()
mc <- sparseMatrix(
i, j, x = w, repr = "C",
) |> forceSymmetric()
# calculate focal mean
bench::mark(
base_r_row = (mr %*% x) / Matrix::rowSums(mr),
base_r_col = (mc %*% x) / Matrix::rowSums(mc),
terra = focal(r, fun = "mean", na.rm = TRUE),
check = FALSE
)
#> # A tibble: 3 × 13
#> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time
#> <bch:expr> <bch:tm> <bch:t> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm>
#> 1 base_r_row 21.4µs 24.27µs 36686. 9.03KB 3.67 9999 1 273ms
#> 2 base_r_col 18.66µs 19.76µs 48278. 3.31KB 0 10000 0 207ms
#> 3 terra 1.04ms 1.09ms 877. 4.05KB 2.17 404 1 460ms
#> # ℹ 4 more variables: result <list>, memory <list>, time <list>, gc <list>
@mdsumner
Copy link

what's filter_row() ?

@JosiahParry
Copy link
Author

Ope! @mdsumner it removes the NaN values I believe it was defined like so:

filter_row <- function(.row) .row[!is.nan(.row)]

@mdsumner
Copy link

Ah I see

Appreciate this example, I never understood use of Matrix but have toyed with my own versions of sparsity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment