Title: | Unbiased Thematic Map Accuracy and Area |
---|---|
Description: | Unbiased estimators of overall and per-class thematic map accuracy and area published in Olofsson et al. (2014) <doi:10.1016/j.rse.2014.02.015> and Stehman (2014) <doi:10.1080/01431161.2014.930207>. |
Authors: | Hugo Costa [aut, cre] |
Maintainer: | Hugo Costa <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.1.2 |
Built: | 2025-01-30 05:07:02 UTC |
Source: | https://github.com/hagc/mapaccuracy |
Implements the estimators described in Olofsson et al. (2013, 2014) for overall accuracy, producer's accuracy, user's accuracy, and area. Includes precision estimates.
olofsson(r, m, Nh, margins = TRUE)
olofsson(r, m, Nh, margins = TRUE)
r |
character vector. Reference class labels. The object will be coerced to factor. |
m |
character vector. Map class labels. The object will be coerced to factor. |
Nh |
numeric vector. Area, number of pixels, or proportion of the classes in the map. It must be named (see details). |
margins |
logical. If |
Argument Nh
must be named to explicitly and clearly identify the class that each area refers to.
The order of Nh
will be used for displaying the results.
In the error matrix returned, the entries corresponding to no observed cases will present
NA
rather than 0
. This is to emphasize the difference between the absence of cases
and the presence of some (few) cases that represent a very small proportion of area (almost
zero) and thus possibly rounded to zero. However, NA
means zero proportion of area.
A list with the estimates and error matrix.
OA |
overall accuracy |
UA |
user's accuracy |
PA |
producer's accuracy |
area |
area proportion |
SEoa |
standard error of OA |
SEua |
standard error of UA |
SEpa |
standard error of PA |
SEa |
standard error of area proportion |
matrix |
confusion error (area proportion). Rows and columns represent map and reference class labels, respectively |
Hugo Costa
Olofsson, P.; Foody, G. M.; Stehman, S. V.; Woodcock, C. E. (2013). Making better use of accuracy data in land change studies: Estimating accuracy and area and quantifying uncertainty using stratified estimation. Remote Sens. Environ., 129, 122-131.
Olofsson, P.; Foody, G. M.; Herold, M.; Stehman, S. V.; Woodcock, C. E.; Wulder, M. A. (2014). Good practices for estimating area and assessing accuracy of land change. Remote Sens. Environ., 148, 42-57.
## Example 1 in Olofsson et al. (2013) r<-c(rep("1",102),rep("2",280),rep("3",118)) m<-c(rep("1",97) ,rep("2",3), rep("3",2),rep("2",279), "3",rep("1",3),rep("2",18),rep("3",97)) Nh<-c(22353, 1122543, 610228) names(Nh)<-c("1", "2", "3") a<-olofsson(r, m, Nh) # compare to paper: a$area[1] # eq. 9 a$area[1]*sum(Nh) # eq. 10 a$SEa[1]*sum(Nh) # eq. 12 a$area[1]*sum(Nh)-qnorm(0.975)*a$SEa[1]*sum(Nh) # 95% CI lower bound (note typo in the paper) a$area[1]*sum(Nh)+qnorm(0.975)*a$SEa[1]*sum(Nh) # 95% CI upper bound a$UA[1] # eq. 14 a$PA[1] # eq. 15 a$OA # eq. 16 a$UA # table 4 qnorm(0.975)*a$SEua # table 4 a$PA # table 4 qnorm(0.975)*a$SEpa # table 4 a$matrix # table 4 ## Example 2 in Olofsson et al. (2013) r<-c(rep("1", 129), rep("2", 403), rep("3", 611)) m<-c(rep("1", 127), "2", "2", rep("1", 66), rep("2", 322), rep("3", 15), rep("1", 54), rep("2", 17), rep("3", 540)) Nh<-c(0.007, 0.295, 0.698) names(Nh)<-c("1", "2", "3") b<-olofsson(r, m, Nh) # compare to paper (table 6): b$OA qnorm(0.975)*b$SEoa b$UA qnorm(0.975)*b$SEua b$PA qnorm(0.975)*b$SEpa ## Example of table 8 in Olofsson et al. (2014) r<-c(rep(1,69),rep(2,56),rep(3,175),rep(4,340)) m<-c(rep(1,66), 3, rep(4,2), rep(2,55), 4, rep(1,5), rep(2,8), rep(3,153),rep(4,9),rep(1,4),rep(2,12),rep(3,11),rep(4,313)) r[r==1] <- m[m==1] <- "Deforestation" r[r==2] <- m[m==2] <- "Forest gain" r[r==3] <- m[m==3] <- "Stable forest" r[r==4] <- m[m==4] <- "Stable non-forest" Nh<-c("Deforestation"=200000, "Forest gain"=150000, "Stable forest"=3200000, "Stable non-forest"=6450000) * 30^2 # Landsat pixel area = 30^2 e<-olofsson(r, m, Nh) # compare to paper, left-hand of p. 54: e$UA # User's accuracy qnorm(0.975)*e$SEua # 95% CI width e$PA # Producer's accuracy qnorm(0.975)*e$SEpa # 95% CI width e$OA # Overall accuracy qnorm(0.975)*e$SEoa # 95% CI width # compare to paper, right-hand of p. 54: e$area[1]*sum(Nh)/10000 # deforestation in hectares qnorm(0.975)*e$SEa[1]*sum(Nh)/10000 # 95% CI width in hectares e$area[2]*sum(Nh)/10000 # forest gain in hectares qnorm(0.975)*e$SEa[2]*sum(Nh)/10000 # 95% CI width in hectares e$area[3]*sum(Nh)/10000 # stable forest in hectares qnorm(0.975)*e$SEa[3]*sum(Nh)/10000 # 95% CI width in hectares e$area[4]*sum(Nh)/10000 # stable non-forest in hectares qnorm(0.975)*e$SEa[4]*sum(Nh)/10000 # 95% CI width in hectares # change class order olofsson(r, m, Nh[c(4,2,1,3)]) # m (map) may include classes not found in r (reference) r<-c(rep("1",102),rep("2",280),rep("3",118)) m<-c(rep("1",97) ,rep("2",3), rep("3",2),rep("2",279), "3",rep("1",3),rep("2",18),rep("3",95), rep("4",2)) Nh<-c("1"=22353, "2"=1122543, "3"=610228, "4"=10) olofsson(r, m, Nh) # r (reference) may include classes not found in m (map) r<-c(rep("1",102),rep("2",280),rep("3",116),rep("4",2)) m<-c(rep("1",97) ,rep("2",3), rep("3",2),rep("2",279), "3",rep("1",3),rep("2",18),rep("3",97)) Nh<-c("1"=22353, "2"=1122543, "3"=610228) olofsson(r, m, Nh) # can add classes not found neither in r nor m Nh<-c(Nh, "9"=0) olofsson(r, m, Nh)
## Example 1 in Olofsson et al. (2013) r<-c(rep("1",102),rep("2",280),rep("3",118)) m<-c(rep("1",97) ,rep("2",3), rep("3",2),rep("2",279), "3",rep("1",3),rep("2",18),rep("3",97)) Nh<-c(22353, 1122543, 610228) names(Nh)<-c("1", "2", "3") a<-olofsson(r, m, Nh) # compare to paper: a$area[1] # eq. 9 a$area[1]*sum(Nh) # eq. 10 a$SEa[1]*sum(Nh) # eq. 12 a$area[1]*sum(Nh)-qnorm(0.975)*a$SEa[1]*sum(Nh) # 95% CI lower bound (note typo in the paper) a$area[1]*sum(Nh)+qnorm(0.975)*a$SEa[1]*sum(Nh) # 95% CI upper bound a$UA[1] # eq. 14 a$PA[1] # eq. 15 a$OA # eq. 16 a$UA # table 4 qnorm(0.975)*a$SEua # table 4 a$PA # table 4 qnorm(0.975)*a$SEpa # table 4 a$matrix # table 4 ## Example 2 in Olofsson et al. (2013) r<-c(rep("1", 129), rep("2", 403), rep("3", 611)) m<-c(rep("1", 127), "2", "2", rep("1", 66), rep("2", 322), rep("3", 15), rep("1", 54), rep("2", 17), rep("3", 540)) Nh<-c(0.007, 0.295, 0.698) names(Nh)<-c("1", "2", "3") b<-olofsson(r, m, Nh) # compare to paper (table 6): b$OA qnorm(0.975)*b$SEoa b$UA qnorm(0.975)*b$SEua b$PA qnorm(0.975)*b$SEpa ## Example of table 8 in Olofsson et al. (2014) r<-c(rep(1,69),rep(2,56),rep(3,175),rep(4,340)) m<-c(rep(1,66), 3, rep(4,2), rep(2,55), 4, rep(1,5), rep(2,8), rep(3,153),rep(4,9),rep(1,4),rep(2,12),rep(3,11),rep(4,313)) r[r==1] <- m[m==1] <- "Deforestation" r[r==2] <- m[m==2] <- "Forest gain" r[r==3] <- m[m==3] <- "Stable forest" r[r==4] <- m[m==4] <- "Stable non-forest" Nh<-c("Deforestation"=200000, "Forest gain"=150000, "Stable forest"=3200000, "Stable non-forest"=6450000) * 30^2 # Landsat pixel area = 30^2 e<-olofsson(r, m, Nh) # compare to paper, left-hand of p. 54: e$UA # User's accuracy qnorm(0.975)*e$SEua # 95% CI width e$PA # Producer's accuracy qnorm(0.975)*e$SEpa # 95% CI width e$OA # Overall accuracy qnorm(0.975)*e$SEoa # 95% CI width # compare to paper, right-hand of p. 54: e$area[1]*sum(Nh)/10000 # deforestation in hectares qnorm(0.975)*e$SEa[1]*sum(Nh)/10000 # 95% CI width in hectares e$area[2]*sum(Nh)/10000 # forest gain in hectares qnorm(0.975)*e$SEa[2]*sum(Nh)/10000 # 95% CI width in hectares e$area[3]*sum(Nh)/10000 # stable forest in hectares qnorm(0.975)*e$SEa[3]*sum(Nh)/10000 # 95% CI width in hectares e$area[4]*sum(Nh)/10000 # stable non-forest in hectares qnorm(0.975)*e$SEa[4]*sum(Nh)/10000 # 95% CI width in hectares # change class order olofsson(r, m, Nh[c(4,2,1,3)]) # m (map) may include classes not found in r (reference) r<-c(rep("1",102),rep("2",280),rep("3",118)) m<-c(rep("1",97) ,rep("2",3), rep("3",2),rep("2",279), "3",rep("1",3),rep("2",18),rep("3",95), rep("4",2)) Nh<-c("1"=22353, "2"=1122543, "3"=610228, "4"=10) olofsson(r, m, Nh) # r (reference) may include classes not found in m (map) r<-c(rep("1",102),rep("2",280),rep("3",116),rep("4",2)) m<-c(rep("1",97) ,rep("2",3), rep("3",2),rep("2",279), "3",rep("1",3),rep("2",18),rep("3",97)) Nh<-c("1"=22353, "2"=1122543, "3"=610228) olofsson(r, m, Nh) # can add classes not found neither in r nor m Nh<-c(Nh, "9"=0) olofsson(r, m, Nh)
Implements the estimators described in Stehman (2014) for overall accuracy, producer's accuracy, user's accuracy, and area. Includes precision estimates.
stehman2014(s, r, m, Nh_strata, margins = TRUE, order)
stehman2014(s, r, m, Nh_strata, margins = TRUE, order)
s |
character vector. Strata class labels. The object will be coerced to factor. |
r |
character vector. Reference class labels. The object will be coerced to factor. |
m |
character vector. Map class labels. The object will be coerced to factor. |
Nh_strata |
numeric vector. Number of pixels forming each stratum. It must be named (see details). |
margins |
logical. If |
order |
(optional) character vector. Classes to be displayed in the results and their sequence.
If missing, equal to |
Argument Nh_strata
must be named to explicitly and clearly identify the stratum that
each entry refers to. The names of Nh_strata
are expected to match the strata class
labels of argument s
.
In the error matrix returned, the entries corresponding to no observed cases will present
NA
rather than 0. This is to emphasize the difference between the absence of cases
and the presence of some (few) cases that represent a very small proportion of area (almost
zero) and thus possibly rounded to zero. However, NA
means zero proportion of area.
A list with the estimates and error matrix.
OA |
overall accuracy |
UA |
user's accuracy |
PA |
producer's accuracy |
area |
area proportion |
SEoa |
standard error of OA |
SEua |
standard error of UA |
SEpa |
standard error of PA |
SEa |
standard error of area proportion |
matrix |
confusion error (area proportion). Rows and columns represent map and reference class labels, respectively |
Hugo Costa
Stehman, S. V. (2014). Estimating area and map accuracy for stratified random sampling when the strata are different from the map classes. Int. J. Remote Sens., 35, 4923-4939.
# Numerical example in Stheman (2014) s<-c(rep("A",10), rep("B",10), rep("C",10), rep("D",10)) m<-c(rep("A",7), rep("B",3), "A", rep("B",11), rep("C",6), "B", "B", rep("D",10)) r<-c(rep("A",5), "C", "B", "A", "B", "C", "A", rep("B",5), "A", "A", "B", "B", rep("C",5), "D", "D", "B", "B", "A", rep("D",7), "C", "C", "B") Nh_strata<-c(40000, 30000, 20000, 10000) names(Nh_strata)<-c("A", "B", "C", "D") e<-stehman2014(s, r, m, Nh_strata) e$area[1] # Proportion of area of class A (compare with paper in p. 4932) e$area[3] # Proportion of area of class C (p. 4932) e$OA # Overall accuracy (p. 4932) e$UA[2] # User's accuracy of class B (compare with paper in p. 4934) e$PA[2] # Producer's accuracy of class B (p. 4934) e$matrix[2,3] # Cell (2, 3) of the error matrix (p. 4935) e$SEa[1] # Standard error (SE) for proportion of area of class A (p. 4935) e$SEa[3] # Standard error (SE) for proportion of area of class C (p. 4935) e$SEoa # SE for overall accuracy (p. 4936) e$SEua[2] # SE for user's accuracy of class B (p. 4936) e$SEpa[2] # SE for producer's accuracy of class B (p. 4936) # change class order stehman2014(s, r, m, Nh_strata, order=c("D","C","B","A")) # the number (and name) of strata and map classes may differ s<-c(rep("a",5), rep("aa",5), rep("b",10), rep("c",10), rep("d",10)) Nh_strata<-c("a"=20000, "aa"=20000, "b"=30000, "c"=20000, "d"=10000) stehman2014(s, r, m, Nh_strata) # m (map) may include classes not found in r (reference) m<-c(rep("A",7), rep("B",3), "A", rep("B",11), rep("C",6), "B", "B", rep("D",9), "XX") stehman2014(s, r, m, Nh_strata) # r (reference) may include classes not found in m (map) m<-c(rep("A",7), rep("B",3), "A", rep("B",11), rep("C",6), "B", "B", rep("D",10)) r<-c(rep("A",5), "C", "B", "A", "B", "C", "A", rep("B",5), "A", "A", "B", "B", rep("C",5), "D", "D", "B", "B", "A", rep("D",7), "C", "C", "YY") stehman2014(s, r, m, Nh_strata) # can add classes not found neither in r nor m stehman2014(s, r, m, Nh_strata, order=c("A","B","C","D","YY","ZZ"))
# Numerical example in Stheman (2014) s<-c(rep("A",10), rep("B",10), rep("C",10), rep("D",10)) m<-c(rep("A",7), rep("B",3), "A", rep("B",11), rep("C",6), "B", "B", rep("D",10)) r<-c(rep("A",5), "C", "B", "A", "B", "C", "A", rep("B",5), "A", "A", "B", "B", rep("C",5), "D", "D", "B", "B", "A", rep("D",7), "C", "C", "B") Nh_strata<-c(40000, 30000, 20000, 10000) names(Nh_strata)<-c("A", "B", "C", "D") e<-stehman2014(s, r, m, Nh_strata) e$area[1] # Proportion of area of class A (compare with paper in p. 4932) e$area[3] # Proportion of area of class C (p. 4932) e$OA # Overall accuracy (p. 4932) e$UA[2] # User's accuracy of class B (compare with paper in p. 4934) e$PA[2] # Producer's accuracy of class B (p. 4934) e$matrix[2,3] # Cell (2, 3) of the error matrix (p. 4935) e$SEa[1] # Standard error (SE) for proportion of area of class A (p. 4935) e$SEa[3] # Standard error (SE) for proportion of area of class C (p. 4935) e$SEoa # SE for overall accuracy (p. 4936) e$SEua[2] # SE for user's accuracy of class B (p. 4936) e$SEpa[2] # SE for producer's accuracy of class B (p. 4936) # change class order stehman2014(s, r, m, Nh_strata, order=c("D","C","B","A")) # the number (and name) of strata and map classes may differ s<-c(rep("a",5), rep("aa",5), rep("b",10), rep("c",10), rep("d",10)) Nh_strata<-c("a"=20000, "aa"=20000, "b"=30000, "c"=20000, "d"=10000) stehman2014(s, r, m, Nh_strata) # m (map) may include classes not found in r (reference) m<-c(rep("A",7), rep("B",3), "A", rep("B",11), rep("C",6), "B", "B", rep("D",9), "XX") stehman2014(s, r, m, Nh_strata) # r (reference) may include classes not found in m (map) m<-c(rep("A",7), rep("B",3), "A", rep("B",11), rep("C",6), "B", "B", rep("D",10)) r<-c(rep("A",5), "C", "B", "A", "B", "C", "A", rep("B",5), "A", "A", "B", "B", rep("C",5), "D", "D", "B", "B", "A", rep("D",7), "C", "C", "YY") stehman2014(s, r, m, Nh_strata) # can add classes not found neither in r nor m stehman2014(s, r, m, Nh_strata, order=c("A","B","C","D","YY","ZZ"))