library(dplyr)
library(ggplot2)
library(gridExtra)
library(efdm)
data(example)
theme_set(theme(legend.position = "bottom", axis.text.x = element_text(angle = -90)))
Statespace is the collection of all possible states of classifying variables and can be obtained from actprob by removing the activity probabilities (in our case, thin = thinning, ff = final felling, noman = no management). It is used for constructing transition probabilities.
<- example$actprob %>% select(-c(thin, ff, noman))
statespace head(statespace)
#> region soil sp vol age
#> 1 South Mineral other 1 1
#> 2 South Mineral other 1 2
#> 3 South Mineral other 1 3
#> 4 South Mineral other 1 4
#> 5 South Mineral other 1 5
#> 6 South Mineral other 1 6
Use pair data to estimate transition probabilities for actitivies no management and thinning.
head(example$noman_pairs)
#> region soil sp vol0 vol1 age0 age1
#> 1 South Mineral spruce 10 7 13 14
#> 2 South Mineral spruce 8 8 20 21
#> 3 South Mineral other 9 10 5 6
#> 4 South Mineral other 1 1 1 2
#> 5 South Mineral other 7 8 2 3
#> 6 South Mineral other 7 10 5 6
Statespace and prior are used to fill the missing combinations from pairdata. Here we simply assume that age grows by one age class if no data is seen. Transitions are estimated separately for each region and species. The esimation procedure uses data from different soil types with less weight than the correct soil type.
<- define_activity("noman", c("vol", "age"))
act <- build_statespace(act, statespace,
act factors=c("soil"), by=c("region","sp"))
<- estimatetransprobs(act, example$noman_pairs, prior_grow("age")) noman
<- define_activity("thin", c("vol", "age"))
act <- build_statespace(act, statespace,
act factors=c("soil"), by=c("region","sp"))
<- estimatetransprobs(act, example$thin_pairs, prior_grow("age")) thin
Final felling sets age and volume class to the smallest class. No pairdata is needed/utilized.
<- define_activity("ff", c("vol", "age"))
ff transprobs(ff) <- unique(statespace %>% select(vol0=vol, age0=age)) %>% mutate(vol1=1, age1=1, prob=1)
head(transprobs(ff))
#> vol0 age0 vol1 age1 prob
#> 1 1 1 1 1 1
#> 2 1 2 1 1 1
#> 3 1 3 1 1 1
#> 4 1 4 1 1 1
#> 5 1 5 1 1 1
#> 6 1 6 1 1 1
The activities are collected to a list. The initial state and activity probabilities and the number of time steps are the remaining parameters of the runEFDM
function
<- list(noman, thin, ff)
activities <- example$initial_state
state0 <- example$actprob
actprob head(actprob)
#> region soil sp vol age noman thin ff
#> 1 South Mineral other 1 1 0.976 0.023 0.001
#> 2 South Mineral other 1 2 0.981 0.019 0.000
#> 3 South Mineral other 1 3 0.994 0.006 0.000
#> 4 South Mineral other 1 4 0.991 0.008 0.001
#> 5 South Mineral other 1 5 0.764 0.024 0.212
#> 6 South Mineral other 1 6 0.974 0.025 0.001
EFDM is run for 20 time steps. The length of timestep is determined by the inventory data used to be 5 years.
<- runEFDM(state0, actprob, activities, 20)
states1 head(states1)
#> soil region sp vol age area activity time
#> 1 Mineral Middle other 1 1 101627.6564 noman 0
#> 2 Mineral Middle other 1 2 73660.4310 noman 0
#> 3 Mineral Middle other 1 3 26299.4701 noman 0
#> 4 Mineral Middle other 1 4 5982.8223 noman 0
#> 5 Mineral Middle other 1 5 379.4954 noman 0
#> 6 Mineral Middle other 1 6 1104.1126 noman 0
runEFDM produces a data.frame of areas allocated to each activity at each timestep.
To obtain total growing stock volume, volume coeffiecients are used. The volume coefficients and drain were estimated based on the species composition and changes in timber assortments linked to management activities observed in the forest inventory data.
head(example$vol_coef)
#> vol sp species volume
#> 1 1 other all 0.506323
#> 2 10 other all 176.677720
#> 3 11 other all 210.438071
#> 4 12 other all 245.009871
#> 5 13 other all 279.955533
#> 6 14 other all 314.900072
Drain and income….
head(example$drain_coef)
#> vol sp drain assort activity
#> 1 1 other 0.000000 saw ff
#> 2 1 spruce 0.000000 saw ff
#> 3 2 other 0.000000 saw ff
#> 4 2 spruce 0.000000 saw ff
#> 5 3 other 0.000000 saw ff
#> 6 3 spruce 1.012518 saw ff
Income is loosely linked to the actual timber assortment prices in unit eur/m3.
head(example$income_coef)
#> assort activity euro
#> 1 saw ff 56
#> 2 saw thin 44
#> 3 pulp ff 20
#> 4 pulp thin 15
Simulation timesteps are mutated to mid-years of simulation steps:
<- states1 %>% mutate(time = factor(2016 + time*5)) states1
Growing stock
<-merge(states1, example$vol_coef) %>% mutate (volume=area*volume)
tilstateggplot(subset(tilstate,species!='all')) + scale_fill_viridis_d(end = 0.9) +
geom_bar(aes(x=time, weight=volume/1000000000,fill=species)) +
labs(y=NULL,title=expression(paste("Growing stock, bil.",m^3)), x="Year", fill="")
Age distribution
$ageclass <- cut(states1$age, breaks=c(0,10,20,30,35), include.lowest = TRUE,
states1#labels=c("0-50","51-100","101-150","150+"))
labels=c("-50","-100","-150","150+"))
$region <- factor(states1$region, labels = c("South", "Middle", "North"))
states1ggplot(subset(states1, time %in% c(2016,2066,2116))) +
geom_bar(aes(x=ageclass, weight=area/1000000, fill=region)) +
scale_fill_viridis_d(end = 0.9) +
facet_grid(cols=vars(time)) + labs(y=NULL, title="Area, mill.ha", x="Ageclass", fill=NULL)
First the drain in units m3/ha is converted in into eur/ha. Then multiplication with area (ha) gives the euros.
<- merge(example$drain_coef, example$income_coef) %>% mutate(euro = euro*drain)
euro<- merge(states1, euro) %>% mutate(income=euro*area)
removal
ggplot(subset(removal,!time %in% c(2116))) +
geom_bar(aes(x=time, weight=income/5000000000, fill=assort)) +
scale_fill_viridis_d(end = 0.9) +
labs(y=NULL,title = "Income, bil.€/year", x="5-year intervals", fill=NULL )
In this example the tree species changes after final felling. Therefore we redefine final felling activity taking into account in addition to volume and age also the dominant species. The change depends on region and dominant species. Volume and age act as before. They more to the smallest classes (vol1=1 and age1=1).
<- define_activity("ff", c("vol", "age", "sp"))
ff_age_species transprobs(ff_age_species) <- unique(filter(statespace) %>%
select(vol0=vol, age0=age, sp0=sp, region)) %>%
group_by(region, sp0, vol0, age0) %>%
summarize(data.frame(vol1=1, age1=1, sp1=c('other','spruce'),
prob=case_when(sp0=='other' && region=='South' ~ c(1, 0),
=='other' && region=='Middle' ~ c(1, 0),
sp0=='other' && region=='North' ~ c(0.8, 0.2),
sp0=='spruce' && region=='South' ~ c(0.3, 0.7),
sp0=='spruce' && region=='Middle' ~ c(0.2, 0.8),
sp0=='spruce' && region=='North' ~ c(0, 1))))
sp0#> `summarise()` has grouped output by 'region', 'sp0', 'vol0', 'age0'. You can override using the `.groups` argument.
<- list(noman, thin, ff_age_species)
activities2 <- runEFDM(state0, actprob, activities2, 20) states2
First we add two land use classes to the statespace. Agriculture is classified according to region and soil type, while other land use is only classified accoring to region.
<- statespace
statespace3 $landuse <- "forest"
statespace3<- unique(statespace3 %>% mutate(sp=0, vol=0, age=0, landuse="agri"))
agri <- unique(statespace3 %>% mutate(soil=0, sp=0, vol=0, age=0, landuse="other"))
other <- rbind(statespace3, agri, other) statespace3
We use separate activities for deforestation to each land use class. Variables not used by the agriculture are set to 0. Soil type and region are not changing as a result of deforestation to agriculture.
<- define_activity("defor_to_agri",
defor_to_agri c("vol", "age", "sp", "landuse"))
transprobs(defor_to_agri) <- unique(filter(statespace3, landuse=="forest") %>%
select(vol0=vol, age0=age, sp0=sp,landuse0=landuse) %>%
mutate(vol1=0, age1=0, sp1=0, landuse1="agri", prob=1))
Deforestation to other land use also changes soil type to 0.
<- define_activity("defor_to_other",
defor_to_other c("soil", "vol", "age", "sp", "landuse"))
transprobs(defor_to_other) <- unique(filter(statespace3, landuse=="forest") %>%
select(soil0=soil, vol0=vol, age0=age, sp0=sp,landuse0=landuse) %>%
mutate(soil1=0, vol1=0, age1=0, sp1=0, landuse1="other", prob=1))
Afforestation only applies to agriculture. Volume and age classes start from 1 and the area is split evenly to spruce and other species.
<- define_activity("affor", c("vol", "age", "sp", "landuse"))
affor <- filter(statespace3, landuse=="agri") %>%
aff select(soil, vol0=vol, age0=age, region, sp0=sp, landuse0=landuse) %>%
mutate(vol1=1, age1=1, sp1="other", landuse1="forest", prob=1)
<- rbind(aff %>% mutate(sp1="spruce", prob=0.5),
aff %>% mutate(sp1="other", prob=0.5))
aff transprobs(affor) <- aff
A donothing activity is used for non-forest land uses, when there is nothing forestry related going on.
<- define_activity("donothing", character())
donothing <- list(noman, thin, ff, defor_to_other, defor_to_agri, affor, donothing) activities3
adding land use information to state
<- state0
state03 $landuse <- "forest"
state03<- rbind(state03, agri %>% mutate(area=rep(c(1552000/2,997000/2,76000/2),each=2)),
state03 %>% mutate(area=c(721000,507000,112000))) other
Activity probabilities for new land uses
<- actprob
actprob3 $defor_to_other <- 0.0002
actprob3$defor_to_agri <- 0.00025
actprob3$affor <- 0
actprob3$landuse <- "forest"
actprob3$donothing <- 0
actprob3<- setdiff(names(actprob3), names(state03))
actnames <- actprob3[actnames]/rowSums(actprob3[actnames])
actprob3[actnames] <- rbind(actprob3,
actprob3 %>% mutate(thin=0, ff=0, noman=0, defor_to_other=0, defor_to_agri=0, affor=0.0005, donothing=0.9995),
agri %>% mutate(thin=0, ff=0, noman=0, defor_to_other=0, defor_to_agri=0, affor=0, donothing=1)) other
<- runEFDM(state03, actprob3, activities3, 20) states3