Skip to content

Commit ddc3c25

Browse files
committed
various updates
1 parent f8ec1ee commit ddc3c25

36 files changed

+224
-158
lines changed

DESCRIPTION

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: LandsatTS
22
Title: An R package to facilitate retrieval, cleaning, cross-calibration, and phenological modeling of Landsat time-series data
3-
Version: 1.0.2
3+
Version: 1.1.0
44
Authors@R:
55
c(
66
person(given = "Logan T.",
@@ -24,7 +24,7 @@ Authors@R:
2424
email = "",
2525
comment = c(ORCID = "0000-0002-6326-4308"))
2626
)
27-
Description: This software package facilitates sample-based time series analysis of surface reflectance and spectral indices derived from sensors on the Landsat satellites. The package includes functions that enable extraction of the full Landsat record for point sample locations or small study regions using Google Earth Engine directly accessed from R. Moreover, the package includes functions for (1) rigorous data cleaning, (2) cross-sensor calibration with machine learning, (3) phenological modeling, and (4) time series analysis.
27+
Description: This software package facilitates sample-based time series analysis of surface reflectance and spectral indices derived from sensors on the Landsat satellites. The package includes functions that enable extraction of the full Landsat record for point sample locations or small study regions using Google Earth Engine directly accessed from R. Moreover, the package includes functions for (1) data cleaning, (2) cross-sensor calibration, (3) phenological modeling, and (4) time series analysis.
2828
License: Modified MIT
2929
Encoding: UTF-8
3030
LazyData: true

LICENSE

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
MIT License
22

3-
Copyright (c) 2021 by
4-
Authors: Logan T. Berner, Jakob J. Assmann, Richard Massey, Signe Normand
5-
and Scott Goetz
6-
Citation: Logan T. Berner, Jakob J. Assmann, Richard Massey, Signe Normand
7-
and Scott J. Goetz. 2021. lsatTS - an R package for deriving
8-
vegetation greenness time series using Landsat satellite data.
9-
https://github.com/logan-berner/lsatTS
3+
Copyright (c) 2022 by
4+
Authors: Logan T. Berner, Jakob J. Assmann, Signe Normand, and Scott Goetz
5+
Citation: Logan T. Berner, Jakob J. Assmann, Signe Normand, and Scott J. Goetz.
6+
2022. LandsatTS: an R package to facilitate retrieval, cleaning, cross-calibration,
7+
and phenological modeling of Landsat time-series data.
8+
https://github.com/logan-berner/LandsatTS
109

1110
Permission is hereby granted, free of charge, to any person obtaining a copy
1211
of this software and associated documentation files (the "Software"), to deal

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export(lsat_fit_phenological_curves)
1212
export(lsat_format_data)
1313
export(lsat_get_pixel_centers)
1414
export(lsat_neighborhood_mean)
15+
export(lsat_plot_trend_hist)
1516
export(lsat_summarize_data)
1617
export(lsat_summarize_growing_seasons)
1718
import(data.table)

NEWS.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
# LandsatTS changelog
22

3-
## 1.0.2 (released: 30 November 2022)
4-
- Changed package name from lsatTS to LandsatTS.
5-
- Added function lsat_calibrate_poly().
3+
## 1.1.0 (released: 2022-12-07)
4+
- Changed package name from lsatTS to LandsatTS
5+
- Added function lsat_calibrate_poly()
6+
- Added function lsat_plot_trend_hist()
7+
- Revised function lsat_fit_phenological_curves() with improve outlier screening
8+
- Revised function lsat_calc_trend() so it no longer creates figures
69

7-
## 1.0.1 (released: 2 June 2022)
10+
## 1.0.1 (released: 2022-6-2)
811
- Bug fix to address error in lsat_get_pixel_centers() caused by change in the URL for the WRS2 geometries hosted by USGS. See Issue #35: https://github.com/logan-berner/lsatTS/issues/35
912

10-
## 1.0.0 (released: 12 April 2022)
13+
## 1.0.0 (released: 2022-4-12)
1114
- First public release of lsatTS.

R/lsat_calc_trend.R

+13-66
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#' Calculate non-parametric vegetation greenness trends
22
#'
33
#' @description This function evaluates and summarizes interannual trends in
4-
#' vegetation greenness for sample sites over a user-specificed time period.
4+
#' vegetation greenness for sample sites over a user-specified time period.
55
#' Potential interannual trends in vegetation greenness are assessed using
66
#' Mann-Kendall trend tests and Theil-Sen slope indicators after prewhitening
77
#' each time series. This trend assessment relies on the zyp.yuepilon() function
@@ -15,13 +15,11 @@
1515
#' @param nyr.min.frac Fraction of years within the time period for which observations
1616
#' must be available if a trend is to be computed.
1717
#' @param sig A p-value significance cutoff used to categories trends (e.g., 0.10)
18-
#' @param legend.position Legend position for output plot, specified as a vector with x and y values
19-
#' ranging from 0 to 1.
20-
#' @param legend.direction Legend direction for output plot, either "horizontal" or "vertical"
21-
#' @return Data.table with summary of temporal trends by site and a multi-panel figure with:
22-
#' (1) a histogram of relative changes in vegetation greenness among sample sites and
23-
#' (2) a time-series plot of mean vegetation greenness for sample sites grouped
24-
#' by trend category.
18+
#' @return A list that includes:
19+
#' (1) a summary message about the mean relative change across sample sites;
20+
#' (2) a data.table summarizing the number and percentage of sites that
21+
#' fall into each trend category;
22+
#' (3) a data.table with trend statistics for each sample site.
2523
#'
2624
#' @export lsat_calc_trend
2725
#' @import data.table
@@ -41,9 +39,7 @@ lsat_calc_trend <- function(dt,
4139
yrs,
4240
yr.tolerance = 1,
4341
nyr.min.frac = 0.66,
44-
sig = 0.10,
45-
legend.position=c(0.8, 0.2),
46-
legend.direction = 'horizontal'){
42+
sig = 0.10){
4743

4844
dt <- data.table::data.table(dt)
4945
data.table::setnames(dt, si, 'si')
@@ -58,7 +54,7 @@ lsat_calc_trend <- function(dt,
5854
site.smry[, trend.period := paste0(min(yrs),'to',max(yrs))]
5955

6056
# note which si is being used
61-
site.smry[, si.name := si]
57+
site.smry[, si := si]
6258

6359
# identify sites with observations within the specified tolerance of first and last years
6460
site.smry[, ':='(first.yr.abs.dif = abs(first.yr - min(yrs)),
@@ -94,57 +90,6 @@ lsat_calc_trend <- function(dt,
9490
trend.dt[pval <= sig & slope < 0, trend.cat := 'browning']
9591
trend.dt[pval > sig, trend.cat := 'no_trend']
9692

97-
# histogram of vegetation greenness trends
98-
fig1 <- ggplot2::ggplot(trend.dt, ggplot2::aes(total.change.pcnt, fill=after_stat(x))) +
99-
ggplot2::geom_histogram(bins = 50, size = 0.25, color = 'gray20') +
100-
ggplot2::scale_fill_gradient2(low="darkgoldenrod4", mid='white', high="darkgreen",
101-
limits = c(-50,50), midpoint = 0) +
102-
ggplot2::labs(y = 'Number of sample sites',
103-
x = paste0("Relative change in Landsat ",
104-
gsub('.MAX', 'max', toupper(si)),
105-
' from ', min(yrs), ' to ', max(yrs), ' (%)')) +
106-
ggplot2::theme_bw() +
107-
ggplot2::theme(legend.position = 'none',
108-
axis.text=ggplot2::element_text(size=12),
109-
axis.title=ggplot2::element_text(size=14)) +
110-
ggplot2::xlim(-50, 50)
111-
112-
# Create time series figure for each trend class
113-
dt <- dt[trend.dt, on = 'sample.id']
114-
115-
trend.cls.yrly.dt <- dt[, .(si.avg = mean(si, na.rm = T), si.sd = sd(si, na.rm = T),
116-
n = .N), by = c('trend.cat','year')]
117-
118-
trend.cls.yrly.dt[, si.se := si.sd/sqrt(n)]
119-
trend.cls.yrly.dt[is.na(si.se), si.se := 0]
120-
121-
trend.cls.yrly.dt[, trend.cat := factor(trend.cat, levels = c('browning','no_trend','greening'),
122-
labels = c('browning','no trend','greening'))]
123-
124-
trend.cls.yrly.dt[, trend.cat := droplevels.factor(trend.cat)]
125-
126-
trend.cols <- data.table(trend.cat = c('browning','no trend','greening'),
127-
cols = c('darkgoldenrod4','ivory3','darkgreen'))
128-
trend.cols <- trend.cols[trend.cat %in% trend.cls.yrly.dt$trend.cat]
129-
130-
fig2 <- ggplot2::ggplot(trend.cls.yrly.dt,
131-
ggplot2::aes(year, si.avg, group = trend.cat, color = trend.cat)) +
132-
ggplot2::labs(y=paste0('Mean Landsat ', gsub('.MAX', 'max', toupper(si))), x='Year') +
133-
ggplot2::geom_ribbon(ggplot2::aes(ymin = si.avg-si.se, ymax = si.avg + si.se, fill=trend.cat),
134-
alpha=0.3, linetype=0)+
135-
ggplot2::geom_line(ggplot2::aes(color = trend.cat), alpha = 1, linewidth=1) +
136-
ggplot2::scale_fill_manual(values = trend.cols$cols, name = 'Trend class') +
137-
ggplot2::scale_color_manual(values = trend.cols$cols, name = 'Trend class')+
138-
ggplot2::theme_bw() +
139-
ggplot2::theme(legend.position=legend.position, legend.direction=legend.direction,
140-
axis.text=ggplot2::element_text(size=12),
141-
axis.title=ggplot2::element_text(size=14),
142-
plot.title=ggplot2::element_text(hjust = 0.5))
143-
144-
# combo figure
145-
fig <- ggpubr::ggarrange(fig1, fig2, ncol = 1, nrow = 2,
146-
labels = c('(a)','(b)'), vjust=0.9, hjust = -0.1)
147-
14893
# create output message about average relative change
14994
avg <- round(mean(trend.dt$total.change.pcnt),2)
15095
std <- round(sd(trend.dt$total.change.pcnt),2)
@@ -159,12 +104,14 @@ lsat_calc_trend <- function(dt,
159104
names(trend.freqs.dt) <- c('Trend category','Number of sites','Percent of sites')
160105

161106
# output
162-
print(fig)
163-
print(print.avg.msg)
164-
print(trend.freqs.dt)
107+
output.message <- list()
108+
output.message$message <- print.avg.msg
109+
output.message$trend.frequencies <- trend.freqs.dt
110+
print(output.message)
165111
trend.dt
166112
}
167113

114+
168115
calc.trends <- function(x,y){
169116
xx <- zyp::zyp.yuepilon(y,x) ## note the order of x and y are switched in this call!!!
170117
return(data.table(slope=round(xx['trend'],5),

R/lsat_plot_trend_hist.R

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#' Create a histogram summarizing relative temporal changes in a spectral index
2+
#' across all sample sites.
3+
#'
4+
#' @param dt A data.table output from lsat_calc_trend()
5+
#' @param xlim Numeric vector specifying the minimum and maximum values for the
6+
#' histogram x-axis.
7+
#'
8+
#' @return A histogram generated by ggplot2
9+
#' @export lsat_plot_trend_hist
10+
#'
11+
#' @examples
12+
#' data(lsat.example.dt)
13+
#' lsat.dt <- lsat_format_data(lsat.example.dt)
14+
#' lsat.dt <- lsat_clean_data(lsat.dt)
15+
#' lsat.dt <- lsat_calc_spectral_index(lsat.dt, 'ndvi')
16+
#' # lsat.dt <- lsat_calibrate_rf(lsat.dt, band.or.si = 'ndvi', write.output = F)
17+
#' lsat.pheno.dt <- lsat_fit_phenological_curves(lsat.dt, si = 'ndvi')
18+
#' lsat.gs.dt <- lsat_summarize_growing_seasons(lsat.pheno.dt, si = 'ndvi')
19+
#' lsat.trend.dt <- lsat_calc_trend(lsat.gs.dt, si = 'ndvi.max', yrs = 2000:2020)
20+
#' lsat_plot_trend_hist(lsat.trend.dt)
21+
22+
lsat_plot_trend_hist <- function(dt, xlim = c(-30,30)){
23+
24+
dt <- data.table::data.table(dt)
25+
si <- first(dt$si)
26+
first.yr <- first(dt$first.yr)
27+
last.yr <- first(dt$last.yr)
28+
29+
# histogram of vegetation greenness trends
30+
hist <- ggplot2::ggplot(dt, ggplot2::aes(total.change.pcnt, fill=after_stat(x))) +
31+
ggplot2::geom_histogram(bins = 50, size = 0.25, color = 'gray20') +
32+
ggplot2::scale_fill_gradient2(low="darkgoldenrod4", mid='white', high="darkgreen",
33+
limits = c(-50,50), midpoint = 0) +
34+
ggplot2::labs(y = 'Number of sample sites',
35+
x = paste0("Relative change in Landsat ",
36+
gsub('.MAX', 'max', toupper(si)),
37+
' from ', first.yr, ' to ', last.yr, ' (%)')) +
38+
ggplot2::theme_bw() +
39+
ggplot2::theme(legend.position = 'none',
40+
axis.text=ggplot2::element_text(size=12),
41+
axis.title=ggplot2::element_text(size=14)) +
42+
ggplot2::xlim(xlim[1], xlim[2])
43+
44+
hist
45+
46+
}

data-raw/generate_external_data_for_itex_examples.R

+11-10
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ itex.sites.dt <- itex.dt %>% rename(sample_id = study_area) %>%
1919
group_by(sample_id) %>%
2020
top_n(n = 1) %>% as.data.table()
2121

22-
itex.sites.dt
22+
# exclude the Bogong site located in Australia
23+
itex.sites.dt <- itex.sites.dt[sample_id != 'Bogong']
2324
save(itex.sites.dt, file="data/itex.sites.dt.RData")
2425

25-
itex.sites.sf <- itex.sites.dt %>% as.data.frame() %>% st_as_sf(coords = c("long", "lat"), crs = 4326)
26-
save(itex.sites.sf, file="data/itex.sites.sf.RData")
27-
28-
jpeg('man/manuscript/figures/itex_site_map.jpg', width = 7, height = 5, units = 'in', res = 300)
29-
plot(st_geometry(ne_countries(returnclass = "sf")))
30-
plot(st_geometry(itex.sites.sf), col = "black", bg = 'red', add = T, pch = 21)
31-
dev.off()
26+
# itex.sites.sf <- itex.sites.dt %>% as.data.frame() %>% st_as_sf(coords = c("long", "lat"), crs = 4326)
27+
# save(itex.sites.sf, file="data/itex.sites.sf.RData")
3228

29+
# jpeg('man/manuscript/figures/itex_site_map.jpg', width = 7, height = 5, units = 'in', res = 300)
30+
# plot(st_geometry(ne_countries(returnclass = "sf")))
31+
# plot(st_geometry(itex.sites.sf), col = "black", bg = 'red', add = T, pch = 21)
32+
# dev.off()
3333

3434

3535
# EXPORT TIME SERIES ==============================================================
@@ -44,5 +44,6 @@ task_list <- lsat_export_ts(pixel_coords_sf = itex.sites.sf,
4444

4545

4646
# GRAB DATA FROM GOOGLE DRIVE AND MOVE TO LOCAL DIRECTORY =========================
47-
itex.lsat.dt <- fread('C:/Users/Logan/My Drive/gee_export/itex_sites_chunk_1.csv')
48-
save(itex.lsat.dt, file="data/itex.lsat.dt.RData")
47+
itex.lsat.dt <- fread('C:/Users/Logan/My Drive/gee_export/itex_sites__chunk_1.csv')
48+
itex.lsat.dt <- itex.lsat.dt[sample_id != "Bogong"]
49+
save(itex.lsat.dt, file="data/itex.lsat.dt.RData")

data/itex.lsat.dt.RData

-34.4 KB
Binary file not shown.

data/itex.sites.dt.RData

-4 Bytes
Binary file not shown.
476 KB
Loading

man/lsat_calc_spectral_index.Rd

+42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/lsat_calc_trend.Rd

+8-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/lsat_calibrate_rf.Rd

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/lsat_clean_data.Rd

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/lsat_evaluate_phenological_max.Rd

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)