View or edit on GitHub
This page is synchronized from trase/data/indonesia/wood_pulp/indicators/q3_2025/qa/gaveau_ioppitp_expansion_2024.md. Last modified on 2025-12-16 22:20 CET by Harry Biddle.
Please view or edit the original file there; changes should be reflected here after a midnight build (CET time),
or manually triggering it with a GitHub action (link).
Incoming data from Gaveau et al. for expansion IOPPITP expansion and
forest cover change Adelina Chandra 2025-06-12
Purpose
This script checks the incoming data, transforms it, and prepares it for further analysis.
- Checks geodatabase and transforms into format that suits GEE
- Quality checks the forest cover change data
- Saves the data to S3
Preparation
# Load required packages
library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
library(ggplot2)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ lubridate 1.9.4 ✔ tibble 3.2.1
✔ purrr 1.0.4 ✔ tidyr 1.3.1
✔ readr 2.1.5
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(sf)
Linking to GEOS 3.13.0, GDAL 3.8.5, PROJ 9.5.1; sf_use_s2() is TRUE
library(terra)
terra 1.8.42
Attaching package: 'terra'
The following object is masked from 'package:tidyr':
extract
library(purrr)
library(patchwork)
Attaching package: 'patchwork'
The following object is masked from 'package:terra':
area
library(aws.signature)
library(aws.s3)
# Sign into S3
aws.signature::use_credentials()
Sys.setenv("AWS_DEFAULT_REGION" = "eu-west-1")
bucket <- "trase-storage"
Read data
# IOPPITP data
ioppitp_gdb_path <- "/vsis3/trase-storage/indonesia/wood_pulp/indicators/ori/q3_2025/Data For Trase_06112025/IOPPITP_Expansion_2024.gdb"
layers <- st_layers(ioppitp_gdb_path)
ioppitp_gdb <- st_read(ioppitp_gdb_path, layer = "IDN_IOPPITP_Expansion2001to2024_Updated_15May2025")
Reading layer `IDN_IOPPITP_Expansion2001to2024_Updated_15May2025' from data source `/vsis3/trase-storage/indonesia/wood_pulp/indicators/ori/q3_2025/Data For Trase_06112025/IOPPITP_Expansion_2024.gdb'
using driver `OpenFileGDB'
Warning in CPL_read_ogr(dsn, layer, query, as.character(options), quiet, : GDAL
Message 1: organizePolygons() received a polygon with more than 100 parts. The
processing may be really slow. You can skip the processing by setting
METHOD=SKIP, or only make it analyze counter-clock wise parts by setting
METHOD=ONLY_CCW if you can assume that the outline of holes is counter-clock
wise defined
Simple feature collection with 3562602 features and 47 fields
Geometry type: MULTIPOLYGON
Dimension: XYZ
Bounding box: xmin: 95.39768 ymin: -8.000588 xmax: 140.9463 ymax: 5.498833
z_range: zmin: 0 zmax: 0
Geodetic CRS: WGS 84
Check data (Skip for faster processing)
glimpse(ioppitp_gdb) #3,562,602 rows; 47 columns; WGS 84 - massive data
Rows: 3,562,602
Columns: 48
$ year <chr> "2000", "2000", "2000", "2000", "2000", "2000", "2000", "…
$ Class <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ gridcode <int> 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 30…
$ F1980s <chr> " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " …
$ F1990 <chr> " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " …
$ F2000 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2001 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2002 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2003 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2004 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2005 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2006 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2007 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2008 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2009 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2010 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2011 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2012 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2013 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2014 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2015 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2016 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2017 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2018 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2019 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2020 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2021 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2022 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2023 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ F2024 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "…
$ CompDriven <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ YearITP <chr> " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " …
$ Note <chr> " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " …
$ Koreksi <chr> " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " …
$ YrBfor2000 <chr> " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " …
$ YrOP <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ TDelay <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ CID <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ District <chr> "Pandeglang", "Pandeglang", "Pandeglang", "Pandeglang", "…
$ Province <chr> "Banten", "Banten", "Banten", "Banten", "Banten", "Banten…
$ Country <chr> "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indo…
$ Region <chr> "Java", "Java", "Java", "Java", "Java", "Java", "Java", "…
$ Area_Ha <dbl> 2.276075e+01, 6.520691e-03, 2.413157e+01, 9.488771e+00, 3…
$ OBJECTID <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ Shape_Leng <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ Shape_Length <dbl> 4.755183e-02, 3.191463e-04, 5.596155e-02, 3.162875e-02, 2…
$ Shape_Area <dbl> 1.861893e-05, 5.333890e-09, 1.973965e-05, 7.761763e-06, 2…
$ Shape <MULTIPOLYGON [°]> MULTIPOLYGON Z (((105.762 -..., MULTIPOLYGON…
# drop geometry - for quicker checks
opt_df <- ioppitp_gdb %>%
as_tibble() %>%
select(-Shape_Leng, -Shape_Area, -Shape_Length, -Shape)
# sapply(opt_df[, sapply(opt_df, is.character)], unique)
# sapply(opt_df, function(x) sum(is.na(x)))
unique(opt_df$gridcode) # this is the value that indicates the type of forest cover change (see the raster data)
[1] 300 304 306 307 308 309 310 311 312 313 314 315 316 317 318
[16] 319 320 301 305 302 303 323 0 321 324 112 114 113 111 322
[31] 100 117 118 120 108 106 104 115 102 110 116 101 109 105 122
[46] 119 123 121 107 124 103 602 400 412 416 419 420 418 417 421
[61] 608 607 606 611 609 612 610 615 613 415 413 619 620 624 409
[76] 601 604 605 621 600 614 616 617 618 622 603 623 422 424 7000
[91] 7005 7014 7015 7016 7017 7018 7019 7020 7021 7004 7007 7008 7009 7011 7012
[106] 7013 5000 5002 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015
[121] 5016 5017 5018 5019 5020 7001 7002 7003 7006 7010 7022 5021 5022 5023 7023
[136] 5001 411 7024 5024 410 1 5003 414 423 408 405 407 9000 9001 9002
[151] 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017
[166] 9018 9019 9020 9021 9022 9023 9024 403 401 406
length(unique(opt_df$gridcode))
[1] 175
# names(opt_df)
# head(opt_df)
# check if CompDriven == 2024 is where F2023 == Forest & F2024 == IOPP/ITP
opt_df %>%
filter(CompDriven == 2024) %>%
select(Class, year, gridcode, F2023, F2024) %>%
group_by(Class, year, gridcode, F2023, F2024) %>%
summarise(n = n()) %>%
ungroup()
`summarise()` has grouped output by 'Class', 'year', 'gridcode', 'F2023'. You
can override using the `.groups` argument.
# A tibble: 6 × 6
Class year gridcode F2023 F2024 n
<chr> <chr> <int> <chr> <chr> <int>
1 IOPP 2024 124 Forest IOPP 9921
2 IOPP 2024 424 Forest IOPP 54
3 IOPP 2024 624 Forest IOPP 811
4 ITP 2024 124 Forest ITP 3027
5 ITP 2024 424 Forest ITP 2
6 ITP 2024 624 Forest ITP 528
# Check if the data is consistent across years
years <- 2001:2024
result_list <- map(years, function(y) {
opt_df %>%
filter(CompDriven == y) %>%
select(Class, year, gridcode,
!!sym(paste0("F", y-1)), !!sym(paste0("F", y))) %>%
group_by(Class, year, gridcode,
!!sym(paste0("F", y-1)), !!sym(paste0("F", y))) %>%
summarise(n = n(), .groups = "drop") %>%
mutate(CompDriven = y)})
all_results <- bind_rows(result_list)
#View(all_results)
sapply(all_results[, sapply(all_results, is.character)], unique)
$Class
[1] "IOPP" "ITP"
$year
[1] "2001" "2002" "2003" "2004" "2005" "2006" "2007" "2008" "2009" "2010"
[11] "2011" "2012" "2013" "2014" "2015" "2016" "2017" "2018" "2019" "2020"
[21] "2021" "2022" "2023" "2024"
$F2000
[1] "Forest" NA
$F2001
[1] "IOPP" "ITP" "Forest" NA
$F2002
[1] NA "IOPP" "ITP" "Forest"
$F2003
[1] NA "IOPP" "ITP" "Forest"
$F2004
[1] NA "IOPP" "ITP" "Forest"
$F2005
[1] NA "IOPP" "ITP" "Forest"
$F2006
[1] NA "IOPP" "ITP" "Forest"
$F2007
[1] NA "IOPP" "ITP" "Forest"
$F2008
[1] NA "IOPP" "ITP" "Forest"
$F2009
[1] NA "IOPP" "ITP" "Forest"
$F2010
[1] NA "IOPP" "ITP" "Forest"
$F2011
[1] NA "IOPP" "ITP" "Forest"
$F2012
[1] NA "IOPP" "ITP" "Forest"
$F2013
[1] NA "IOPP" "ITP" "Forest"
$F2014
[1] NA "IOPP" "ITP" "Forest"
$F2015
[1] NA "IOPP" "ITP" "Forest"
$F2016
[1] NA "IOPP" "ITP" "Forest"
$F2017
[1] NA "IOPP" "ITP" "Forest"
$F2018
[1] NA "IOPP" "ITP" "Forest"
$F2019
[1] NA "IOPP" "ITP" "Forest"
$F2020
[1] NA "IOPP" "ITP" "Forest"
$F2021
[1] NA "IOPP" "ITP" "Forest"
$F2022
[1] NA "IOPP" "ITP" "Forest"
$F2023
[1] NA "IOPP" "ITP" "Forest"
$F2024
[1] NA "IOPP" "ITP"
# all consistent that the data shows forest transition to IOPP/ITP - meaning rapid conversion
#check NA in f2024
# all_results %>% filter(is.na(F2024)) # NA is the case for the years after expansion
unique(all_results$gridcode) # however, the gridcode is not clear due to zero values
[1] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
[20] 601 121 602 403 603 100 604 605 606 122 120 123 608 609 614 615 600 607 407
[39] 408 412 610 409 414 611 612 124 410 422 613 400 421 411 413 416 417 418 423
[58] 424 419 616 617 619 621 622 618 620 415 420 0 623 624
zero_gridcode <- all_results %>% filter(gridcode == 0)
sapply(zero_gridcode[, sapply(zero_gridcode, is.character)], unique)
$Class
[1] "IOPP" "ITP"
$year
[1] "2016" "2017" "2018" "2019" "2020" "2021" "2022" "2023"
$F2000
[1] NA
$F2001
[1] NA
$F2002
[1] NA
$F2003
[1] NA
$F2004
[1] NA
$F2005
[1] NA
$F2006
[1] NA
$F2007
[1] NA
$F2008
[1] NA
$F2009
[1] NA
$F2010
[1] NA
$F2011
[1] NA
$F2012
[1] NA
$F2013
[1] NA
$F2014
[1] NA
$F2015
[1] "Forest" NA
$F2016
[1] "IOPP" "Forest" NA
$F2017
[1] NA "IOPP" "Forest"
$F2018
[1] NA "IOPP" "Forest"
$F2019
[1] NA "IOPP" "Forest"
$F2020
[1] NA "IOPP" "Forest"
$F2021
[1] NA "ITP" "Forest"
$F2022
[1] NA "IOPP" "ITP" "Forest"
$F2023
[1] NA "IOPP" "ITP"
$F2024
[1] NA
# view(zero_gridcode) # there are classes where forest transition happened but gricode is zero
# thus the most important columns are compdriven, class
sum(is.na(opt_df$CompDriven))
[1] 0
unique(opt_df$CompDriven)
[1] 0 2013 2012 2011 2010 2009 2015 2014 2016 2017 2018 2019 2020 2021 2023
[16] 2006 2024 2001 2002 2005 2007 2003 2004 2008 2022
nrow(opt_df) == length(unique(opt_df$OBJECTID)) # false, needs to create unique ID
[1] FALSE
further check stats
# calculate area directly in hectares and add as a new column - compare to Area_Ha
# gdb_data_merc <- st_transform(ioppitp_gdb, 3395)
# gdb_data_merc$calc_area_ha <- as.numeric(st_area(gdb_data_merc)) / 10000
# sum(gdb_data_merc$calc_area_ha[gdb_data_merc$Class == "IOPP"]) # 11080549
# sum(gdb_data_merc$calc_area_ha[gdb_data_merc$Class == "IOPP" & gdb_data_merc$CompDriven > 0]) # 2308282
# View the first few area values
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP"]) # 11062436 - similar to the above - good to go
[1] 11062436
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP" & ioppitp_gdb$CompDriven > 0]) # 2303917 rapid conversion by industry
[1] 2303917
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP" & ioppitp_gdb$CompDriven == 2024]) # 31096.53 rapid expansion only 2024
[1] 31096.53
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP" & ioppitp_gdb$year < 2020]) # 10541982 oil palm up to 2019 - looking at gaveau et al this is industrial only
[1] 10541982
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP" & ioppitp_gdb$year > 2000]) # 6370069 # oil palm expansion after 2000
[1] 6890523
# remember that F2024 is either IOPP or ITP, thus checking the F2023
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP" & ioppitp_gdb$CompDriven == 0 & ioppitp_gdb$F2023 == "Forest"]) # 555.27 - what is this then?
[1] 555.2736
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP" & ioppitp_gdb$CompDriven == 0 & ioppitp_gdb$F2023 == "Non Forest"]) # 84646.55 - also this non-forest to palm transition
[1] 84646.55
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "IOPP" & ioppitp_gdb$CompDriven == 2024 & ioppitp_gdb$F2023 == "Forest"]) # 31096.53
[1] 31096.53
# how about ITP? similar to https://nusantara-atlas.org/industrial-wood-pulp-deforestation-in-indonesia-slows-in-2024/?
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "ITP"]) # 3334775
[1] 3334775
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "ITP" & ioppitp_gdb$CompDriven == 2024]) # 13211.67 - 13,647 in the blogpost
[1] 13211.67
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "ITP" & ioppitp_gdb$CompDriven == 2023]) # 30399.84 - 30,385 in the blogpost
[1] 30399.84
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "ITP" & ioppitp_gdb$CompDriven == 0 & ioppitp_gdb$F2023 == "Non Forest"]) # 59907.58
[1] 59907.58
sum(ioppitp_gdb$Area_Ha[ioppitp_gdb$Class == "ITP" & ioppitp_gdb$CompDriven == 0 & ioppitp_gdb$F2022 == "Non Forest"]) - 59907.58 # 69653.45
[1] 69653.45
Notes on inconsistencies - First, the info on transition in FXXXX is not clear. There are some cases where F2000-2023 is Forest but CompDriven == 0. Why is this not classified as rapid conversion? What does this class represent? - Second, what seems to be consistent is that CompDriven == 2024 and CompDriven == 0 but F2023 was Non-Forest.See the graph in their blog: for 2023 and 2024, the composition from Forest to ITP and Non-Forest to ITP looks somewhat similar. - There are also cases where F2023 is Forest and F2024 is IOPP/ITP, but the gridcode is 0, 100, 400, or 600 (see below). However, for CompDriven data, gridcode is consistently 124, 424, or 624.
Based on information from the Gaveau et al. team: - CompDriven indicates the drivers of forest loss by pulpwood (one year interval). - Thus, for all polygons where the previous year was forest, they should fall under CompDriven != 0. - However, there are many cases where this is not true! In theory, we should exclude them because Gaveau et al. did not categorize them as rapid conversion.
What is clear is: - Where F2023 = Forest, CompDriven == 0, and year == 2024: these should be excluded, since all polygons under this category are classified as forest in 2024 (in the image). The total area for ITP is 432 ha.
More details on errors are in the linked Google Doc.
Clarification from Gaveau et al:
We need to exclude areas with gridcode 0.
# further checking non-forest to palm and wp
opt_df <- ioppitp_gdb %>%
as_tibble() %>%
select(-Shape_Leng, -Shape_Area, -Shape_Length, -Shape)
#further checks misclassified forests
opt_df_misfor <- opt_df %>%
filter(Class == "IOPP") %>%
filter(CompDriven == 0) %>%
count(F2000,F2001,F2002, F2003, F2004, F2005, F2006, F2007, F2008, F2009, F2010,
F2011, F2012, F2013, F2014, F2015, F2016, F2017, F2018, F2019, F2020,
F2021, F2022, F2023, F2024, gridcode) %>% # non IOPP/ITP data
filter(gridcode %in% c(100,400,600))
# view(opt_df_misfor)
#ok all consistent that this should be corrected y-1 forest
opt_df_nonfor <- opt_df %>%
filter(Class == "IOPP") %>%
#filter(CompDriven == 0) %>%
count(F2000,F2023,F2024,CompDriven) # non IOPP/ITP data
head(opt_df_nonfor)
# A tibble: 6 × 5
F2000 F2023 F2024 CompDriven n
<chr> <chr> <chr> <int> <int>
1 Forest Forest IOPP 0 4376
2 Forest Forest IOPP 2024 10786
3 Forest IOPP IOPP 0 193111
4 Forest IOPP IOPP 2001 3438
5 Forest IOPP IOPP 2002 4846
6 Forest IOPP IOPP 2003 3412
opt_df_nonfor_case <- opt_df %>%
filter(Class == "IOPP") %>%
#filter(CompDriven == 0) %>%
#filter(year == 2024) %>%
count(F2001,F2002, F2003, F2004, F2005, F2006, F2007, F2008, F2009, F2010,
F2011, F2012, F2013, F2014, F2015, F2016, F2017, F2018, F2019, F2020,
F2021, F2022, F2023, F2024, CompDriven, gridcode) %>% # non IOPP/ITP data
filter(F2023 == "Forest")
head(opt_df_nonfor_case)
# A tibble: 6 × 27
F2001 F2002 F2003 F2004 F2005 F2006 F2007 F2008 F2009 F2010 F2011 F2012 F2013
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
2 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
3 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
4 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
5 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
6 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
# ℹ 14 more variables: F2014 <chr>, F2015 <chr>, F2016 <chr>, F2017 <chr>,
# F2018 <chr>, F2019 <chr>, F2020 <chr>, F2021 <chr>, F2022 <chr>,
# F2023 <chr>, F2024 <chr>, CompDriven <int>, gridcode <int>, n <int>
this is super insteresting why does some of the data have CompDriven == 0 but F2023 == Forest and F2024 == IOPP/ITP
Summary of meeting with Husna on 7th aug I found some misclassifications within the expansion data (GDB) from Gaveau et al., as the sum of areas does not add up and does not match the figures reported in their blog posts.
ITP blog: https://nusantara-atlas.org/industrial-wood-pulp-deforestation-in-indonesia-slows-in-2024/
IOPP blog: https://nusantara-atlas.org/industrial-palm-oil-deforestation-in-indonesia-slows-slightly-in-2024/
All industry-driven expansions are classified by assigning a year value in the CompDriven field. However, there are thousands of hectares that should fall under this category but are not included. During the meeting, we calculated the totals together, and it was evident that if we combine both the classified and misclassified areas, the sum roughly matches the values reported in the blog post. Note that we only calculated for 2023 and 2024 during the call. This issue applies to both figures for IOPP and ITP.
IOPP: CompDriven == 2024: 31,096.53 ha (while in blog: 31,314 ha) BUT when adding 358 ha misclassified, totals match CompDriven == 2023: 34,410.11 ha (while in blog: 34,353 ha) adding 2.3 ha misclassified, insignificant) ITP: CompDriven == 2024: 13,211.67 ha (blog: 13,647 ha) but adding 432.9 ha misclassified, totals match) CompDriven == 2023: 30,399.84 ha (blog: 30,385 ha; no misclassified areas)
This discrepancy makes sense, as Husna explained that she used the forest image layer and then ‘corrected’ it using digitized industrial pulpwood areas. However, she mentioned that the value in small areas often did not get updated during the reclassification.
Since the calculation now add up, she agreed that I should proceed with correcting the data. We also agreed to remove Gridcode == 0 Other topic: Peat data used to calculate PeatSwamp extent was MoEF’s data.
sapply(opt_df_nonfor[, sapply(opt_df_nonfor, is.character)], unique)
$F2000
[1] "Forest" "IOPP" "ITP" "Non Forest"
$F2023
[1] "Forest" "IOPP" "Non Forest"
$F2024
[1] "IOPP"
opt_df_nonfor %>% select(CompDriven)
# A tibble: 36 × 1
CompDriven
<int>
1 0
2 2024
3 0
4 2001
5 2002
6 2003
7 2004
8 2005
9 2006
10 2007
# ℹ 26 more rows
unique(opt_df_nonfor$CompDriven) # 0
[1] 0 2024 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
[16] 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
#check itp
opt_df_case_itp <- opt_df %>%
filter(Class == "ITP") %>%
#filter(CompDriven == 0) %>%
#filter(year == 2024) %>%
count(F2001,F2002, F2003, F2004, F2005, F2006, F2007, F2008, F2009, F2010,
F2011, F2012, F2013, F2014, F2015, F2016, F2017, F2018, F2019, F2020,
F2021, F2022, F2023, F2024, CompDriven, gridcode) %>% # non IOPP/ITP data
filter(F2023 == "Forest")
head(opt_df_case_itp)
# A tibble: 6 × 27
F2001 F2002 F2003 F2004 F2005 F2006 F2007 F2008 F2009 F2010 F2011 F2012 F2013
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
2 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
3 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
4 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
5 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
6 Forest Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore… Fore…
# ℹ 14 more variables: F2014 <chr>, F2015 <chr>, F2016 <chr>, F2017 <chr>,
# F2018 <chr>, F2019 <chr>, F2020 <chr>, F2021 <chr>, F2022 <chr>,
# F2023 <chr>, F2024 <chr>, CompDriven <int>, gridcode <int>, n <int>
#should be excluded?
opt_df_exclude_itp <- opt_df %>%
filter(Class == "ITP" & CompDriven == 0) %>%
#filter(year == 2023) %>%
filter(gridcode %in% c(100,400,600,0))
sum(opt_df_exclude_itp$Area_Ha) # 2400 ha - quite huge! so why excluding 100,400,600 then?
[1] 2400.162
opt_df_exclude_itp_count <- opt_df_exclude_itp %>%
count(F2001,F2002, F2003, F2004, F2005, F2006, F2007, F2008, F2009, F2010,
F2011, F2012, F2013, F2014, F2015, F2016, F2017, F2018, F2019, F2020,
F2021, F2022, F2023, F2024, CompDriven, year, gridcode) # non IOPP/ITP data
head(opt_df_exclude_itp)
# A tibble: 6 × 44
year Class gridcode F1980s F1990 F2000 F2001 F2002 F2003 F2004 F2005 F2006
<chr> <chr> <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 2024 ITP 0 <NA> <NA> Forest Forest Forest Fore… Fore… Fore… Fore…
2 2024 ITP 100 <NA> <NA> Forest Forest Forest Fore… Fore… Fore… Fore…
3 2024 ITP 100 <NA> <NA> Forest Forest Forest Fore… Fore… Fore… Fore…
4 2024 ITP 100 <NA> <NA> Forest Forest Forest Fore… Fore… Fore… Fore…
5 2024 ITP 100 <NA> <NA> Forest Forest Forest Fore… Fore… Fore… Fore…
6 2024 ITP 100 <NA> <NA> Forest Forest Forest Fore… Fore… Fore… Fore…
# ℹ 32 more variables: F2007 <chr>, F2008 <chr>, F2009 <chr>, F2010 <chr>,
# F2011 <chr>, F2012 <chr>, F2013 <chr>, F2014 <chr>, F2015 <chr>,
# F2016 <chr>, F2017 <chr>, F2018 <chr>, F2019 <chr>, F2020 <chr>,
# F2021 <chr>, F2022 <chr>, F2023 <chr>, F2024 <chr>, CompDriven <int>,
# YearITP <chr>, Note <chr>, Koreksi <chr>, YrBfor2000 <chr>, YrOP <int>,
# TDelay <int>, CID <int>, District <chr>, Province <chr>, Country <chr>,
# Region <chr>, Area_Ha <dbl>, OBJECTID <int>
ok in the oil palm 2024 update the data capture when forest or non forest is converted to IOPP but not when forest is converted to non-forest and subsequently into IOPP lets follow this stucture
Transform data
# create unique ID for IOPP and ITP
ioppitp_gdb_uid <- ioppitp_gdb %>%
mutate(uid = case_when(Class == "IOPP" ~ paste0("P_", row_number()),
Class == "ITP" ~ paste0("T_", row_number()),
TRUE ~ "problem"))
length(unique(ioppitp_gdb_uid$uid))
[1] 3562602
sum(ioppitp_gdb_uid$uid == 'problem')
[1] 0
# separate IOPP and ITP data
iopp_df <- ioppitp_gdb_uid %>%
filter(Class == "IOPP")
# nrow(iopp_df) # 2,615,627
itp_df <- ioppitp_gdb_uid %>%
filter(Class == "ITP")
# nrow(itp_df) # 946,975
Prepare for exporting
# dropping 3d geometry due to error in st_write
iopp_df_2d <- st_zm(iopp_df, drop = TRUE, what = "ZM")
itp_df_2d <- st_zm(itp_df, drop = TRUE, what = "ZM")
# check if the data is valid
sum(st_is_valid(iopp_df_2d)) # many invalid geometries -600k
[1] 2508944
sum(st_is_valid(itp_df_2d)) # 40k invalid geometries
[1] 906894
# quick fix for invalid geometries
iopp_df_2d_valid <- st_make_valid(iopp_df_2d)
itp_df_2d_valid <- st_make_valid(itp_df_2d)
# check again before exporting
sum(st_is_valid(iopp_df_2d_valid))
[1] 2615627
sum(st_is_valid(itp_df_2d_valid))
[1] 946975
# glimpse(itp_df_2d_valid)
# empty geometries
sum(st_is_empty(iopp_df_2d_valid)) #331
[1] 331
which(st_is_empty(iopp_df_2d_valid))
[1] 660 2254 11164 36863 36864 36865 36937 36938 36939
[10] 38250 43250 63403 64845 67059 67060 69106 69948 72999
[19] 73306 82709 82735 88195 89610 93319 93581 97592 103295
[28] 103869 104032 104033 107993 112741 112742 112745 112746 112747
[37] 113297 113298 113487 113905 113906 114754 115259 125372 134582
[46] 134596 134597 134611 148232 160443 169846 175735 177583 178069
[55] 178072 178073 178074 178775 183797 183883 183884 184021 196405
[64] 203813 204281 208824 216240 226618 238095 238097 239720 240558
[73] 240595 243313 243314 243315 243316 255588 258116 260801 262259
[82] 290686 294221 295688 295689 295690 295691 295693 295701 295703
[91] 295706 295707 295712 295713 295715 295716 295717 295718 295719
[100] 295720 295721 295723 295724 295725 295726 295733 295734 295735
[109] 295736 295737 295740 295743 295744 295747 295759 295782 295783
[118] 295784 295788 295795 295796 295801 295803 295807 295836 295837
[127] 298615 342168 343561 353045 387610 415386 435049 436187 436190
[136] 436191 436192 436194 436195 439307 440266 447701 447707 447709
[145] 460843 469430 469433 469434 469446 495241 510094 528031 529261
[154] 534922 540522 540525 540526 540527 540528 540529 540530 541949
[163] 546259 547810 549388 566686 570163 632603 634195 642288 715540
[172] 777309 801355 834963 853939 853940 853941 856200 895544 898274
[181] 903397 905449 969461 976726 1045224 1059907 1063657 1069761 1077906
[190] 1088800 1094423 1097609 1131672 1131995 1174470 1177970 1181600 1210176
[199] 1212761 1256283 1259171 1262277 1283985 1283986 1286620 1290865 1315078
[208] 1331865 1343060 1344823 1348430 1363698 1412608 1415315 1416814 1422138
[217] 1427490 1430958 1457489 1461893 1461902 1463774 1467382 1477753 1480513
[226] 1480515 1487424 1490842 1521420 1527940 1527944 1527948 1527949 1527950
[235] 1532796 1532797 1533071 1533072 1535490 1535491 1535494 1535512 1535527
[244] 1535532 1539289 1542863 1542864 1542865 1542866 1542867 1542868 1542869
[253] 1542870 1542871 1542872 1542873 1542875 1542876 1542877 1542878 1552578
[262] 1555012 1568832 1578546 1585404 1585408 1594974 1611486 1616062 1641992
[271] 1665895 1713669 1737612 1743802 1786206 1790481 1821011 1842230 1851944
[280] 1857400 1878026 1897093 1905909 1933386 1957037 1969993 1974052 1997753
[289] 2001185 2045909 2063538 2108701 2125339 2131507 2168158 2191027 2213391
[298] 2225318 2240443 2266511 2268144 2369005 2369006 2369068 2369071 2384408
[307] 2388274 2425597 2441476 2493585 2499474 2501126 2509828 2547620 2554558
[316] 2576649 2576650 2577763 2578063 2578972 2579291 2580523 2582767 2585909
[325] 2590598 2597113 2597975 2598264 2598542 2600894 2607977
sum(st_is_empty(itp_df_2d_valid)) #79
[1] 79
which(st_is_empty(itp_df_2d_valid))
[1] 40305 57430 74630 83793 92907 113336 128984 131254 131255 134123
[11] 140100 140101 140102 140103 142197 142200 157447 213518 213519 213520
[21] 215738 250624 256119 291982 292016 299289 312156 314758 318821 334784
[31] 352260 357787 363763 369662 410240 412038 416034 416035 440095 455302
[41] 458200 505079 537734 561045 571153 610910 614241 628677 628678 628679
[51] 629535 647917 655125 684946 686739 699798 703658 704289 704820 735141
[61] 747542 751129 753504 768275 768277 768279 768281 768283 768286 778160
[71] 797104 797513 797795 806717 817008 818618 828987 904193 905167
# should we be worried?
# iopp_df_2d_empty <- iopp_df_2d_valid[st_is_empty(iopp_df_2d_valid), ]
# sum(iopp_df_2d_empty$Area_Ha) # 0.01378832 ha
# itp_df_2d_empty <- itp_df_2d_valid[st_is_empty(itp_df_2d_valid), ]
# sum(itp_df_2d_empty$Area_Ha) # 0.000396351 ha #very small areas - will be excluded since rasterization will not work with empty geometries
# remove empty geometries
iopp_df_2d_valid <- iopp_df_2d_valid[!st_is_empty(iopp_df_2d_valid), ]
itp_df_2d_valid <- itp_df_2d_valid[!st_is_empty(itp_df_2d_valid), ]
Prepare clean shapefile and perform correction for misclassified polygons as agreed on meeting with Husna on 7th August
iopp_df_final <- iopp_df_2d_valid %>%
select(uid, year, gridcode, starts_with("F20"), CompDriven,
District, Province, Country, Region, Area_Ha) %>%
filter(gridcode != 0) %>% #exclude gridcode 0
rename("CompDriven_init" = "CompDriven") %>% #change CompDriven initial (before correction) to CompDriven_init just to makesure we're keeping record
mutate(CompDriven = ifelse(CompDriven_init == 0 & year != 2000 & gridcode %in% c(100,400,600), year, CompDriven_init), #correct the misclassified
CompDriven = as.numeric(CompDriven))
# check_rev_p <- iopp_df_final %>%
# filter(CompDriven_init == 0 & CompDriven>0) %>%
# select(year, CompDriven_init, CompDriven, gridcode)
# sum(check_rev_p$CompDriven_init != check_rev_p$CompDriven, na.rm = TRUE) #14926 polygon changed classification
itp_df_final <- itp_df_2d_valid %>%
select(uid, year, gridcode, starts_with("F20"), CompDriven,
District, Province, Country, Region, Area_Ha) %>%
filter(gridcode != 0) %>% #exclude gridcode 0
rename("CompDriven_init" = "CompDriven") %>% #change CompDriven initial (before correction) to CompDriven_init just to makesure we're keeping record
mutate(CompDriven = ifelse(CompDriven_init == 0 & year != 2000 & gridcode %in% c(100,400,600), year, CompDriven_init), #correct the misclassified
CompDriven = as.numeric(CompDriven))
glimpse(itp_df_final)
Rows: 946,882
Columns: 36
$ uid <chr> "T_7326", "T_7327", "T_7328", "T_7329", "T_7330", "T_7…
$ year <chr> "2000", "2000", "2000", "2000", "2000", "2000", "2000"…
$ gridcode <int> 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,…
$ F2000 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2001 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2002 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2003 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2004 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2005 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2006 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2007 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2008 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2009 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2010 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2011 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2012 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2013 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2014 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2015 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2016 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2017 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2018 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2019 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2020 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2021 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2022 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2023 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ F2024 <chr> "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP", "ITP"…
$ CompDriven_init <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ District <chr> "Way Kanan", "Way Kanan", "Way Kanan", "Way Kanan", "W…
$ Province <chr> "Lampung", "Lampung", "Lampung", "Lampung", "Lampung",…
$ Country <chr> "Indonesia", "Indonesia", "Indonesia", "Indonesia", "I…
$ Region <chr> "Sumatra", "Sumatra", "Sumatra", "Sumatra", "Sumatra",…
$ Area_Ha <dbl> 6.921000e-01, 2.239206e-01, 3.180442e-02, 4.808438e-01…
$ Shape <POLYGON [°]> POLYGON ((104.5593 -4.58316..., POLYGON ((104.…
$ CompDriven <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
# check_rev_t <- itp_df_final %>%
# filter(CompDriven_init == 0 & CompDriven>0) %>%
# select(year, CompDriven_init, CompDriven, gridcode)
# sum(check_rev_t$CompDriven_init != check_rev_t$CompDriven, na.rm = TRUE) #4569 polygon changed classification
RAPID conversion only
clean shapefile for conversion to image where first digit indicates the current land cover (palm), and the two last are the year when it was established thus the loss year for palm 400, for timber 300 shows other transition (non-forest to pulp, and if already timber in 2000 no history prior 2000, also ITP to palm (only for iopp data) - should be excluded in the deforestation analysis)
unique(iopp_df_final$CompDriven) # 2001-2024.
[1] 0 2013 2012 2011 2010 2009 2015 2014 2016 2017 2018 2019 2020 2021 2023
[16] 2006 2024 2001 2002 2005 2007 2003 2004 2008 2022
`%nin%` <- Negate(`%in%`)
iopp_df_rapid <- iopp_df_final %>%
mutate(foresttopalm = case_when(
CompDriven == 0 ~ 400, #other transitions (indirect, eventually converted or already itp in 2000)
CompDriven >= 2000 ~ 200 + (CompDriven - 2000),
TRUE ~ NA_real_))
glimpse(iopp_df_rapid)
Rows: 2,614,975
Columns: 37
$ uid <chr> "P_1", "P_2", "P_3", "P_4", "P_5", "P_6", "P_7", "P_8"…
$ year <chr> "2000", "2000", "2000", "2000", "2000", "2000", "2000"…
$ gridcode <int> 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,…
$ F2000 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2001 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2002 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2003 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2004 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2005 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2006 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2007 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2008 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2009 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2010 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2011 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2012 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2013 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2014 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2015 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2016 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2017 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2018 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2019 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2020 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2021 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2022 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2023 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ F2024 <chr> "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP", "IOPP"…
$ CompDriven_init <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ District <chr> "Pandeglang", "Pandeglang", "Pandeglang", "Pandeglang"…
$ Province <chr> "Banten", "Banten", "Banten", "Banten", "Banten", "Ban…
$ Country <chr> "Indonesia", "Indonesia", "Indonesia", "Indonesia", "I…
$ Region <chr> "Java", "Java", "Java", "Java", "Java", "Java", "Java"…
$ Area_Ha <dbl> 2.276075e+01, 6.520691e-03, 2.413157e+01, 9.488771e+00…
$ Shape <POLYGON [°]> POLYGON ((105.762 -6.806987..., POLYGON ((105.…
$ CompDriven <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ foresttopalm <dbl> 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,…
sum(iopp_df_rapid$Area_Ha[iopp_df_rapid$foresttopalm == 223])
[1] 34366.39
itp_df_rapid <- itp_df_final %>%
mutate(foresttotimber = case_when(
CompDriven == 0 ~ 300, #other transitions (indirect)
CompDriven >= 2000 ~ 100 + (CompDriven - 2000),
TRUE ~ NA_real_))
sum(itp_df_rapid$Area_Ha[itp_df_rapid$foresttotimber== 124]) # great
[1] 13644.66
unique(itp_df_rapid$foresttotimber)
[1] 300 121 123 110 111 119 120 106 107 108 109 112 113 114 124 103 104 105 122
[20] 115 116 101 102 117 118
unique(itp_df_rapid$foresttotimber)
[1] 300 121 123 110 111 119 120 106 107 108 109 112 113 114 124 103 104 105 122
[20] 115 116 101 102 117 118
RAPID and INDIRECT (ultimately CONVERTED)
AXYY for Woodpulp A = 1 = Rapid conversion - one year interval 3 = eventually converted for Palm A = 2 = Rapid conversion - one year interval 4 = eventually converted X = 1 = forest in mineral soil, 4 = mangrove forest, 6 = peat swamp forest, 3 = non forest, 5 = ITP (applies only for palm), 0 = already IOPP/ITP in 2000 Y = year when converstion to plantation happened. When running on GEE be sure to exclude any 1000, 2000, 31YY, 34YY, 36YY, 41YY, 44YY, 46YY because the 31,34,36,41,44,46 should have been under CompDriven != 0 if they are meant to be included by Gaveau et al. Rapid and indirect conversion IOPP
# quick check
iopp_df %>% filter(is.na(year)) #no NA!
Simple feature collection with 0 features and 48 fields
Bounding box: xmin: NA ymin: NA xmax: NA ymax: NA
Geodetic CRS: WGS 84
[1] year Class gridcode F1980s F1990
[6] F2000 F2001 F2002 F2003 F2004
[11] F2005 F2006 F2007 F2008 F2009
[16] F2010 F2011 F2012 F2013 F2014
[21] F2015 F2016 F2017 F2018 F2019
[26] F2020 F2021 F2022 F2023 F2024
[31] CompDriven YearITP Note Koreksi YrBfor2000
[36] YrOP TDelay CID District Province
[41] Country Region Area_Ha OBJECTID Shape_Leng
[46] Shape_Length Shape_Area Shape uid
<0 rows> (or 0-length row.names)
check00 <- itp_df %>% filter(year == 2000)
unique(check00$F2000)
[1] "ITP"
unique(check00$gridcode)
[1] 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
[16] 315 316 317 318 319 320 321 101 105 106 108 109 111 112 113
[31] 114 118 119 323 322 102 104 107 110 115 116 117 103 100 5000
[46] 5001 5002 5011 5013 7000 7001 7002 7003 7004 7005 7006 7007 7009 7010 7011
[61] 7012 7013 7014 7015 7016 7017 7018 7019 7020 5009 5010 7008 7021 120
# ITP
itp_df_clean <- itp_df_final %>%
#as_tibble() %>% #initally used to make it faster in checking the logic
#slice_sample(n = 50000) %>% #initally used to make it faster in checking the logic
rowwise() %>%
mutate(
year_num = as.numeric(year),
prev_cover = ifelse(year_num > 2000,
get(paste0("F", year_num - 1)),
ifelse(year_num == 2000 & F2000 == "ITP", F2000, NA_character_)),
conversion_itp = case_when(
# Rapid conversion: forest to ITP in one year interval year (CompDriven value is the year)
CompDriven > 0 & prev_cover == "Forest" ~
paste0("1", str_sub(as.character(gridcode), 1, 1), str_pad(year_num %% 100, 2, pad = "0")),
# Conversion from non-forest to ITP
CompDriven == 0 & prev_cover == "Non Forest" ~
paste0("33", str_pad(year_num %% 100, 2, pad = "0")),
# already ITP in 2000, not a new conversion - second digit is 0
CompDriven == 0 & prev_cover == "ITP" ~
paste0("30", str_pad(year_num %% 100, 2, pad = "0")),
# !!! After correction - this should not exist, but we correct it just to be sure!
# forest and shows history to plantation, but CompDriven == 0 but forest in y-1)
CompDriven == 0 & prev_cover == "Forest" & year_num > 2000 ~
paste0("1", str_sub(as.character(gridcode), 1, 1), str_pad(year_num %% 100, 2, pad = "0")),
# Everything else is not handled
TRUE ~ NA_character_
)
) %>%
ungroup()
# check if the classification is ok!
# view(itp_df_clean %>% select(year_num, gridcode, CompDriven, prev_cover, conversion_itp))
unique(itp_df_clean$prev_cover)
[1] "ITP" "Non Forest" "Forest"
unique(itp_df_clean$conversion_itp)
[1] "3000" "3323" "3324" "3301" "3302" "3303" "3304" "3305" "3306" "3307"
[11] "3308" "3309" "3310" "3311" "3312" "3313" "3314" "3315" "3316" "3317"
[21] "3318" "3319" "3320" "3321" "3322" "1121" "1123" "1110" "1111" "1119"
[31] "1120" "1106" "1107" "1108" "1109" "1112" "1113" "1114" "1124" "1103"
[41] "1104" "1105" "1122" "1621" "1622" "1623" "1115" "3016" "1116" "1101"
[51] "1102" "1117" "1118" "1624" "1619" "1620" "1421" "1616" "1423" "1614"
[61] "1615" "1613" "1612" "1605" "1604" "1611" "1610" "1606" "1411" "1410"
[71] "1617" "1618" "1412" "1413" "1414" "1415" "1417" "1420" "1424"
problem <- itp_df_clean %>% filter(conversion_itp == "problem"|is.na(conversion_itp)) %>%
select(year_num, gridcode, CompDriven, prev_cover, F2020, F2021, F2023, F2024, conversion_itp, Area_Ha)
sum(problem$Area_Ha)
[1] 0
sum(is.na(itp_df_clean$conversion_itp))
[1] 0
# unique(problem$gridcode) #exclude - around 10ha
unique(problem$year_num)
numeric(0)
sum(is.na(itp_df_clean$conversion_itp))
[1] 0
# unique(problem$gridcode) #exclude - around 10ha
unique(problem$year_num)
numeric(0)
# SOLVED: what still does not make sense is if we include any polygons that is forest in y-1 BUT
# classified as CompDriven == 0 - in theory they should be CompDriven == 1 (rapid forest conversion)
# thus I am excluding this class - anything starts with 31,34, or 36 for ITP (41,44, and 46 for IOPP)
# clean_itp <- itp_df_clean %>% filter(!str_starts(conversion_itp, "31"),
# !str_starts(conversion_itp, "34"),
# !str_starts(conversion_itp, "36"))
# unique(clean_itp$conversion_itp)
# sum(clean_itp$Area_Ha) #3333656
# sum(itp_df_clean$Area_Ha) #3334338
# 682 ha excluded
# CLEANED
itp_df_all_transition <- itp_df_clean
Rapid and indirect conversion IOPP
iopp_df_clean <- iopp_df_final %>%
rowwise() %>%
mutate(
year_num = as.numeric(year),
prev_cover = ifelse(year_num > 2000,
get(paste0("F", year_num - 1)),
ifelse(year_num == 2000 & F2000 == "IOPP", F2000, NA_character_)),
conversion_iopp = case_when(
# Rapid conversion: forest to IOPP in one year interval year (CompDriven value is the year)
CompDriven > 0 ~ #& prev_cover == "Forest" ~
paste0("2", str_sub(as.character(gridcode), 1, 1), str_pad(year_num %% 100, 2, pad = "0")),
# Conversion from non-forest to IOPP
CompDriven == 0 & prev_cover == "Non Forest" ~
paste0("43", str_pad(year_num %% 100, 2, pad = "0")),
# Conversion from ITP to IOPP - only palm has this transition
CompDriven == 0 & prev_cover == "ITP" ~
paste0("45", str_pad(year_num %% 100, 2, pad = "0")),
# already IOPP in 2000, not a new conversion - second digit is 0
CompDriven == 0 & prev_cover == "IOPP" ~
paste0("40", str_pad(year_num %% 100, 2, pad = "0")),
# !!! Part of correction to makesure that it is consistent
CompDriven == 0 & prev_cover == "Forest" & year_num > 2000 ~
paste0("2", str_sub(as.character(gridcode), 1, 1), str_pad(year_num %% 100, 2, pad = "0")),
# Everything else is not handled
TRUE ~ NA_character_
)
) %>%
ungroup()
unique(iopp_df_clean$prev_cover)
[1] "IOPP" "Non Forest" "Forest" "ITP"
unique(iopp_df_clean$conversion_iopp)
[1] "4000" "4301" "4302" "4303" "4304" "4305" "4306" "4307" "4308" "4309"
[11] "4310" "4311" "4318" "4321" "4312" "4313" "2113" "4314" "4315" "4316"
[21] "4317" "4319" "4320" "4322" "4323" "4324" "2112" "2111" "2110" "2109"
[31] "2115" "2114" "2116" "2117" "2118" "2119" "2120" "2121" "2123" "2106"
[41] "4508" "4514" "2124" "2101" "2102" "2105" "2107" "2103" "2104" "2108"
[51] "4512" "4513" "4509" "4510" "4511" "4515" "2415" "4516" "2418" "2419"
[61] "2420" "2122" "2607" "2611" "2612" "2417" "2624" "4518" "2621" "2619"
[71] "2620" "2622" "2618" "2617" "2421" "2422" "2623" "2424" "2609" "2613"
[81] "2411" "2412" "4501" "4504" "4505" "4506" "4507" "4517" "2423" "2608"
[91] "2615" "2616" "2605" "2610" "2407" "2409" "2410" "2408" "2614" "2403"
[101] "2602" "2606" "4502" "4503" "2601" "2604" "2603" "2413" "2414" "2416"
iopp_df_clean %>% filter(prev_cover == 'ITP')
Simple feature collection with 4694 features and 38 fields
Geometry type: GEOMETRY
Dimension: XY
Bounding box: xmin: 99.88457 ymin: -3.617235 xmax: 116.3442 ymax: 1.372087
Geodetic CRS: WGS 84
# A tibble: 4,694 × 39
uid year gridcode F2000 F2001 F2002 F2003 F2004 F2005 F2006 F2007 F2008
* <chr> <chr> <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 P_136904 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
2 P_136905 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
3 P_136906 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
4 P_136907 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
5 P_136908 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
6 P_136909 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
7 P_136910 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
8 P_136911 2008 300 ITP ITP ITP ITP ITP ITP ITP ITP IOPP
9 P_136912 2008 300 Non … Non … Non … Non … ITP ITP ITP ITP IOPP
10 P_136913 2008 300 Non … Non … Non … Non … ITP ITP ITP ITP IOPP
# ℹ 4,684 more rows
# ℹ 27 more variables: F2009 <chr>, F2010 <chr>, F2011 <chr>, F2012 <chr>,
# F2013 <chr>, F2014 <chr>, F2015 <chr>, F2016 <chr>, F2017 <chr>,
# F2018 <chr>, F2019 <chr>, F2020 <chr>, F2021 <chr>, F2022 <chr>,
# F2023 <chr>, F2024 <chr>, CompDriven_init <int>, District <chr>,
# Province <chr>, Country <chr>, Region <chr>, Area_Ha <dbl>,
# Shape <POLYGON [°]>, CompDriven <dbl>, year_num <dbl>, prev_cover <chr>, …
problem_iopp <- iopp_df_clean %>% filter(conversion_iopp == "problem"|is.na(conversion_iopp)) %>%
select(year_num, gridcode, CompDriven, prev_cover, starts_with('F2'), conversion_iopp, Area_Ha)
problem_iopp_count <- problem_iopp %>%
count(year_num, CompDriven, gridcode, prev_cover, conversion_iopp)
sum(problem_iopp$Area_Ha)
[1] 0
sum(is.na(iopp_df_clean$conversion_iopp))
[1] 0
# SOLVED - unnecessary: excluding any y-1 forest but not rapid conversion
# clean_iopp <- iopp_df_clean %>% filter(!str_starts(conversion_iopp, "41"), !str_starts(conversion_iopp, "44"),
# !str_starts(conversion_iopp, "46"))
# unique(clean_iopp$conversion_iopp)
# sum(clean_iopp$Area_Ha) #11041732
# sum(iopp_df_clean$Area_Ha) #11061716 (19984ha excluded)
# Cleaned
iopp_df_all_transition <- iopp_df_clean
Visualization
# quartz(width = 10, height = 6)
# prep oil palm data for visualization
order <- c("Non Forest", "ITP", "Peat Swamp Forest", "Mangrove Forest", "Forest")
iopp_df_visu <- iopp_df_all_transition %>%
mutate(prev_land_cover = str_sub(as.character(conversion_iopp), 2, 2),
prev_land_cover = case_when(prev_land_cover == 1 ~ "Forest",
prev_land_cover == 4 ~ "Mangrove Forest",
prev_land_cover == 6 ~ "Peat Swamp Forest",
prev_land_cover == 3 ~ "Non Forest",
prev_land_cover == 5 ~ "ITP",
prev_land_cover == 0 ~ "Already palm in 2000",
TRUE ~ "Others")) %>%
mutate(conv_type = ifelse(CompDriven > 0, "Rapid", "Indirect")) %>% #indirect means ultimately converted
group_by(conv_type, year, prev_land_cover) %>%
summarise(Area_Ha = sum(Area_Ha, na.rm = TRUE)) %>%
ungroup()
`summarise()` has grouped output by 'conv_type', 'year'. You can override using
the `.groups` argument.
head(iopp_df_visu)
Simple feature collection with 6 features and 4 fields
Geometry type: GEOMETRY
Dimension: XY
Bounding box: xmin: 95.49075 ymin: -7.60486 xmax: 140.8524 ymax: 5.088223
Geodetic CRS: WGS 84
# A tibble: 6 × 5
conv_type year prev_land_cover Area_Ha Shape
<chr> <chr> <chr> <dbl> <GEOMETRY [°]>
1 Indirect 2000 Already palm in 2000 4171891. MULTIPOLYGON (((120.4202 -2.55…
2 Indirect 2001 ITP 1208. MULTIPOLYGON (((101.0242 0.554…
3 Indirect 2001 Non Forest 91273. MULTIPOLYGON (((103.4517 -2.95…
4 Indirect 2002 ITP 87.7 MULTIPOLYGON (((101.3762 0.892…
5 Indirect 2002 Non Forest 89704. MULTIPOLYGON (((110.8515 -2.42…
6 Indirect 2003 ITP 144. POLYGON ((101.3877 0.8705, 101…
ggplot(iopp_df_visu %>% filter(prev_land_cover != "Already palm in 2000"),
aes(x = as.factor(year), y = Area_Ha/1000, fill = factor(prev_land_cover, levels = order))) +
geom_bar(stat = "identity")+ #position = "dodge") +
scale_fill_viridis_d(option = "D") +
labs(title = "IOPP expansion over time",
x = "Clearing year", y = "Total expansion area (thousand Ha)", fill = "Previous land cover") +
#facet_wrap(~conv_type)+
theme_minimal()

# prepare wood pulp data for visualization
order_itp <- c("Non Forest", "Peat Swamp Forest", "Mangrove Forest", "Forest")
itp_df_visu <- itp_df_all_transition %>%
#filter(CompDriven != 0) %>%
mutate(prev_land_cover = str_sub(as.character(conversion_itp), 2, 2),
prev_land_cover = case_when(prev_land_cover == 1 ~ "Forest",
prev_land_cover == 4 ~ "Mangrove Forest",
prev_land_cover == 6 ~ "Peat Swamp Forest",
prev_land_cover == 3 ~ "Non Forest",
prev_land_cover == 0 ~ "Already woodpulp in 2000",
TRUE ~ "Others")) %>%
mutate(conv_type = ifelse(CompDriven > 0, "Rapid", "Indirect")) %>% #indirect means ultimately converted
group_by(conv_type, year, prev_land_cover) %>%
summarise(Area_Ha = sum(Area_Ha, na.rm = TRUE)) %>%
ungroup()
`summarise()` has grouped output by 'conv_type', 'year'. You can override using
the `.groups` argument.
head(itp_df_visu)
Simple feature collection with 6 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 95.54244 ymin: -6.60075 xmax: 140.6248 ymax: 5.498833
Geodetic CRS: WGS 84
# A tibble: 6 × 5
conv_type year prev_land_cover Area_Ha Shape
<chr> <chr> <chr> <dbl> <MULTIPOLYGON [°]>
1 Indirect 2000 Already woodpulp in 2000 1130291. (((101.4303 0.8559026, 101.…
2 Indirect 2001 Non Forest 30141. (((101.5717 -0.2137218, 101…
3 Indirect 2002 Non Forest 26604. (((103.6612 -3.47648, 103.6…
4 Indirect 2003 Non Forest 13268. (((101.8499 0.08275, 101.84…
5 Indirect 2004 Non Forest 68657. (((103.5184 -3.643, 103.518…
6 Indirect 2005 Non Forest 80277. (((103.5195 -3.50975, 103.5…
ggplot(itp_df_visu %>% filter(prev_land_cover != "Already woodpulp in 2000"),
aes(x = as.factor(year), y = Area_Ha/1000, fill = factor(prev_land_cover, levels = order))) +
geom_bar(stat = "identity")+ #position = "dodge") +
scale_fill_viridis_d(option = "D") +
labs(title = "ITP expansion over time",
x = "Clearing year", y = "Total expansion area (thousand Ha)", fill = "Previous land cover") +
#facet_wrap(~conv_type)+
theme_minimal()

Map the data
# map the IOPP and ITP data
itp_map <- itp_df_visu %>% filter(prev_land_cover != "Already woodpulp in 2000")
map_itp_all_conv <- ggplot() +
geom_sf(data = itp_map, aes(fill = prev_land_cover), alpha = 0.5, color = NA) +
scale_fill_viridis_d(option = "D") +
labs(title = "ITP Expansion Areas") +
theme_minimal() +
theme(legend.position = "bottom")
map_itp_all_conv

iopp_map <- iopp_df_visu %>% filter(prev_land_cover != "Already woodpulp in 2000")
map_iopp_all_conv <- ggplot() +
geom_sf(data = iopp_map, aes(fill = prev_land_cover), alpha = 0.5, color = NA) +
scale_fill_viridis_d(option = "D") +
labs(title = "IOPP Expansion Areas") +
theme_minimal() +
theme(legend.position = "bottom")
map_itp_all_conv

Map Rapid expansion by province
names(itp_map)
[1] "conv_type" "year" "prev_land_cover" "Area_Ha"
[5] "Shape"
province_itp <- unique(itp_df_rapid$Province)
map_itp_rapid_conv <- map(province_itp, function(prov) {
d <- itp_df_rapid %>% filter(foresttotimber != 100, Province == prov)
ggplot() +
geom_sf(data = d, aes(fill = factor(foresttotimber)), alpha = 0.5, color = NA) +
scale_fill_viridis_d(option = "D") +
labs(title = prov) +
theme_minimal() +
theme(
legend.position = "none",
axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank()
)
})
wrap_plots(map_itp_rapid_conv[1:16], ncol = 4, guides = "collect") &
theme(legend.position = "right", panel.grid = element_blank())

province_iopp <- unique(iopp_df_rapid$Province)
map_iopp_rapid_conv <- map(province_iopp, function(prov) {
d <- iopp_df_rapid %>% filter(foresttopalm != 200, Province == prov)
ggplot() +
geom_sf(data = d, aes(fill = factor(foresttopalm)), alpha = 0.5, color = NA) +
scale_fill_viridis_d(option = "D") +
labs(title = prov) +
theme_minimal() +
theme(
legend.position = "none",
axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank()
)
})
wrap_plots(map_iopp_rapid_conv[1:26], ncol = 6, guides = "collect") &
theme(legend.position = "right")

Rasterize and upload to S3
# rasterize
rast_upload <- function(sf_obj, field, s3_bucket, s3_path, res = 0.00025) {
crs_val <- st_crs(sf_obj)
v <- vect(sf_obj)
template <- rast(ext = st_bbox(sf_obj), resolution = res, crs = crs_val$wkt)
r <- rasterize(v, template, field = field)
print(summary(r))
print(plot(r))
temp_file <- tempfile(fileext = ".tif") # write a temp file
writeRaster(r, temp_file, overwrite = TRUE)
put_object(file = temp_file, object = s3_path, bucket = s3_bucket) # upload to S3
unlink(temp_file)
return(r)
}
# define path and bucket
s3_bucket <- "trase-storage"
s3_path_iopp_rapid <- "indonesia/wood_pulp/indicators/in/q3_2025/gaveau_iopp_foresttopalm_rapid_2024.tif"
s3_path_itp_rapid <- "indonesia/wood_pulp/indicators/in/q3_2025/gaveau_itp_foresttotimber_rapid_2024.tif"
s3_path_iopp <- "indonesia/wood_pulp/indicators/in/q3_2025/gaveau_iopp_expansion_2024.tif"
s3_path_itp <- "indonesia/wood_pulp/indicators/in/q3_2025/gaveau_itp_expansion_2024.tif"
# rasterize and upload to S3
r_itp <- rast_upload(
sf_obj = itp_df_rapid,
field = "foresttotimber",
s3_bucket = s3_bucket,
s3_path = s3_path_itp_rapid)
r_iopp <- rast_upload(
sf_obj = iopp_df_rapid,
field = "foresttopalm",
s3_bucket = s3_bucket,
s3_path = s3_path_iopp_rapid)
# all conversion
unique(itp_df_all_transition$conversion_itp) #still has 3000 can be excluded easily in GEE
# rasterize and upload to S3
r_itp_all <- rast_upload(
sf_obj = itp_df_all_transition,
field = "conversion_itp",
s3_bucket = s3_bucket,
s3_path = s3_path_itp)
unique(iopp_df_all_transition$conversion_iopp) #still has 4000 can be excluded easily in GEE
r_iopp_all <- rast_upload(
sf_obj = iopp_df_all_transition,
field = "conversion_iopp",
s3_bucket = s3_bucket,
s3_path = s3_path_iopp)
Shapefile export & save to S3
shp_to_s3 <- function(sf_obj, s3_bucket, s3_prefix, shp_name) {
temp_dir <- tempdir()
temp_shp <- file.path(temp_dir, shp_name)
st_write(sf_obj, temp_shp, delete_dsn = TRUE)
base_name <- tools::file_path_sans_ext(shp_name)
shp_files <- list.files(temp_dir, pattern = paste0("^", base_name, "\\."), full.names = TRUE)
for (f in shp_files) {
put_object(
file = f,
object = file.path(s3_prefix, basename(f)),
bucket = s3_bucket
)
}
file.remove(shp_files)
}
# raw data that has been geometrically corrected
#only rapid
shp_to_s3(
iopp_df_rapid %>% select(uid, year, gridcode, CompDriven, foresttopalm, District, Province, Area_Ha),
s3_bucket,
"indonesia/wood_pulp/indicators/in/q3_2025",
"gaveau_iopp_rapid_expansion_2024.shp"
)
shp_to_s3(
itp_df_rapid %>% select(uid, year, gridcode, CompDriven, foresttotimber, District, Province, Area_Ha),
s3_bucket,
"indonesia/wood_pulp/indicators/in/q3_2025",
"gaveau_itp_rapid_expansion_2024.shp"
)
# all transitions
shp_to_s3(
iopp_df_all_transition %>% select(uid, year, gridcode, CompDriven, prev_cover, conversion_iopp, District, Province, Area_Ha),
s3_bucket,
"indonesia/wood_pulp/indicators/in/q3_2025",
"gaveau_iopp_all_expansion_2024.shp"
)
shp_to_s3(
itp_df_all_transition %>% select(uid, year, gridcode, CompDriven, prev_cover, conversion_itp, District, Province, Area_Ha),
s3_bucket,
"indonesia/wood_pulp/indicators/in/q3_2025",
"gaveau_itp_all_expansion_2024.shp"
)