-
Notifications
You must be signed in to change notification settings - Fork 2
/
EFA markdown.Rmd
2251 lines (1955 loc) · 91 KB
/
EFA markdown.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "AICCRA - EFA"
author: "Peter Steward"
date: "5/12/2022"
output: html_notebook
runtime: shiny
---
<style type="text/css">
.main-container {
max-width: 1800px;
margin-left: auto;
margin-right: auto;
}
</style>
```{r Setup, include=FALSE}
knitr::opts_knit$set(root.dir = "C:/r_projects/AICCRA_EFA")
#knitr::opts_knit$set(root.dir = getwd())
knitr::opts_chunk$set(echo = F)
```
```{r Setup - load packages,echo=F,message=FALSE}
if(!require("pacman", character.only = TRUE)){install.packages("pacman",dependencies = T)}
required.packages <- c("colourpicker",
"data.table",
"dplyr",
"DT",
"FAOSTAT",
"jrvFinance",
"raster",
"RJSONIO",
"terra",
"shiny",
"sf",
"viridis")
pacman::p_load(char=required.packages,install = T,character.only = T)
options(scipen = 999)
```
```{r Setup - source functions,echo=F,message=FALSE}
source("EFA functions.R")
```
## AICCRA - Economic and Financial Analysis Tool (EFAt) {.tabset .tabset-fade .tabset-pills}
**Plotting Parameters**
:::: {style="display: flex;"}
::: {}
```{r Plot - Palette,echo=F}
selectInput(inputId="Palette",
label="Fill palette",
choices = c("magma","inferno","plasma","viridis","cividis","rocket","mako","turbo"),
selected="turbo",
multiple = F,
width="100px")
```
:::
:::{}
```{r Plot - Text size,echo=F}
numericInput(inputId="TextSize",
label="Text size",
value = 1.2,
min=1,
max=20,
step = 0.1,
width="100px")
```
:::
:::{}
```{r Plot - Base width,echo=F}
numericInput(inputId="PlotBaseWidth",
label="Plot width (px)",
value = 1200,
min=100,
max=5000,
step = 100,
width="150px")
```
:::
:::{}
```{r Plot - Adjust height, echo=F}
numericInput(inputId="Plot.Height",
label="Adjust height",
value=0.5,
min=0.1,
max=3,
step=0.1,
width="120px")
```
:::
:::{}
```{r Plot - Adjust width , echo=F}
numericInput(inputId="Plot.Width",
label="Adjust width",
value=1,
min=0.1,
max=3,
step=0.1,
width="120px")
```
:::
:::{}
```{r Plot - Legend position,echo=F}
selectInput(inputId="LegPos",
label="Legend position (factors only)",
choices = c("bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right","center"),
selected="bottomleft",
multiple = F,
width="250px")
```
:::
:::{}
```{r Plot - Legend columns,echo=F}
numericInput(inputId="LegCols",
label="Legend columns",
value = 2,
min=1,
max=20,
step = 1,
width="130px")
```
:::
:::{}
```{r Plot - Border width , echo=F}
numericInput(inputId="borderwidth",
label="Border width",
value=2,
min=0.1,
max=3,
step=0.1,
width="120px")
```
:::
:::{}
```{r Plot - log plots , echo=F}
selectInput(inputId="log_plots",
label="Log plot values?",
choices = c("Yes", "No"),
selected="No",
multiple = F,
width="160px")
```
:::
::::
:::: {style="display: flex;"}
::: {}
```{r Plot - Polygon boundary colour picker core, echo =F}
colourInput(inputId="BorderColCore",
label="Core country border colour",
value="#000000")
```
:::
:::{}
```{r Plot - Polygon boundary colour picker spill, echo =F}
colourInput(inputId="BorderColSpill",
label="Spillover country border colour",
value="#000000")
```
:::
::::
```{r Plot - Create bar height and width functions, echo=F}
Plot.Height <- function(){input$PlotBaseWidth*input$Plot.Height}
Plot.Width <- function(){input$PlotBaseWidth*input$Plot.Width}
```
### Approach
This economic and financial analysis (EFA) of project benefits is designed to explore:
* Increased productivity and enhanced climate resilience (reduced production variability) of technology adoption
* More widespread adoption of CSA technologies due to regional spillovers.
*Caveat: These benefits fall under the sphere of influence of the Project, but not under the sphere of control, because they depend in part on factors beyond the control of the Project (e.g., price incentives, availability of purchased inputs, weather conditions, etc.).*
The EFA is carried out in several stages:
1. **Datasets tab:** Choose the core and spillover countries that will benefit from project activities;
2. **Datasets tab:** Choose farm classification system and target classes;
3. **Datasets tab:** Choose target crops, type of MapSPAM cropping system (e.g. rainfed, irrigated or all) and type of MapSPAM area statistic (physical area or harvested area);
4. **Datasets tab:** Choose target Herrero livestock categories;
5. **Analysis tab:** Set-up project parameters such as expected annual productivity increments and adoption rates, the spillover factor to neighboring countries, a benefit-cost ratio representative of farming systems in the focal area, and project economic parameters (total cost, duration, discounting rate, starting year of returns).
6. **Analysis tab: Productivity increment value** Calculate the value of the benefit that would result from a chosen % increase in crop and livestock productivity over the selected core and spillover areas (the increment can be adjusted);
7. **Analysis tab: Marginal increase in value** The value of improved productivity is converted to range of plausible adoption rates and productivity increments at scale.
8. **Analysis tab: Avoided losses from reduction in CV** One way to translate reduced yield variability into production benefits is to calculate the economic losses avoided (in terms of value of production) for a percentage reduction in yield CV, measured with respect to the left-hand tail of the production distribution. A very approximate estimate is to assume that maize yields in farmers’ fields are distributed normally and calculate the difference in the probability densities of two normal yield density curves, one with the observed mean and yield CV and another with the same mean but a reduced yield CV. In practice, mean yields will increase through the use of CIS, but as explained above the focus here is on the avoided losses, which may be extremely important for household food security.
9. **Analysis tab: Investment indicators** For the range of productivity increments and adoption rates specified, with or without avoided losses from CIS use, three economic indicators are calculated for project performance: Net Present Value (NPV), Internal Rate of Return (IRR) and Benefit Cost Ratio (BCR ). The project duration, discount rate, starting year of returns and project cost are all adjustable.
All spatial variables are standardized to grids of 5 arcminute resolution (9.26 km or 85.75km2 at the equator).
### Datasets {.tabset .tabset-fade .tabset-pills}
```{r Datasets - Set base raster,echo=F}
# Set Base Raster
BaseRaster<-terra::rast("Data/cell5m_livestock_vop.tif")
```
**Core and spillover countries**
*Choose core countries 1st (changing core resets spillover) and always keep 1 core country selected else the script may crash*
```{r Geographies - Load CGIAR countries (evaluated),echo=F,eval=T}
CGIAR_countries_sf<-sf::read_sf("Data/CGIAR_region/CGIAR_countries_simplified.shp",options = "ENCODING=UTF8")
CGIAR_countries_sf<-CGIAR_countries_sf[CGIAR_countries_sf$CG_REG %in% c("ESA","WCA") |
CGIAR_countries_sf$ADMIN %in% c("Morocco","Western Sahara","Libya","Egypt","Algeria","Tunisia","Sudan"),]
sf::st_crs(CGIAR_countries_sf)<-4326
CGIAR_countries_sf$ADMIN[CGIAR_countries_sf$ADMIN=="United Republic of Tanzania"]<-"Tanzania"
CGIAR_countries_sf$ADMIN[CGIAR_countries_sf$ADMIN=="Ivory Coast"]<-"Cote d'Ivoire"
CGIAR_countries<-terra::vect(CGIAR_countries_sf)
```
:::: {style="display: flex;"}
::: {}
```{r Geographies - Choose core countries}
AICCRAcountries<-c("Kenya","Ethiopia","Ghana","Mali","Senegal","Zambia")
checkboxGroupInput(inputId="CountriesChoice",
label= "Core countries",
choices = sort(CGIAR_countries$ADMIN),
selected = "Kenya",
inline = T)
```
:::
:::{}
```{r Geographies - Choose spillover countries}
AICCRAspillcountries<-c("Burundi","Rwanda","Tanzania","Uganda","Benin","Burkina Faso","Chad","Cote d'Ivoire",
"Cameroon","Guinea","Gambia","Guinea-Bissau","Mauritania","Niger","Nigeria","Togo",
"Botswana","Malawi","Mozambique","Zimbabwe")
renderUI({
checkboxGroupInput(inputId="SpillCountriesChoice",
label= "Spillover countries",
choices = sort(CGIAR_countries$ADMIN[!CGIAR_countries$ADMIN %in% input$CountriesChoice]),
selected = NULL,
inline = T)
})
ExtractBy.Core<-reactive({
CGIAR_countries[CGIAR_countries$ADMIN %in% input$CountriesChoice]
})
ExtractBy.Spillover<-reactive({
CGIAR_countries[CGIAR_countries$ADMIN %in% input$SpillCountriesChoice]
})
ExtractBy.All<-reactive({
CGIAR_countries[CGIAR_countries$ADMIN %in% c(input$SpillCountriesChoice,input$CountriesChoice)]
})
```
:::
::::
**Farming systems** *you must select 1 or more*
```{r Farming Systems - Atlas, echo=F,eval=T}
if(!file.exists("Data/Farming_systems/FS1.tif")){
FarmSys<-terra::vect("Data/Farming_systems/fs_lev_2_update.shp")
FarmSys$LEV1_DESC<-data.table::tstrsplit(FarmSys$LEV1_DESC,"[.] ",keep=2)[[1]]
FarmSys$LEV1_DESC<-gsub(" farming system","",FarmSys$LEV1_DESC)
FarmSys$LEV2_DESC<-gsub(" farming system| subsystem","",FarmSys$LEV2_DESC)
FarmSys$Code1<-unlist(lapply(strsplit(FarmSys$LEV1_DESC," "),FUN=function(X){
paste(
c(
stringr::str_to_title(substr(X[1],1,2)),
stringr::str_to_title(substr(X[2:length(X)],1,1))
),collapse="")
}))
FarmSys$Code2<-unlist(lapply(strsplit(FarmSys$LEV2_DESC," |-"),FUN=function(X){
paste(
c(
stringr::str_to_title(substr(X[1],1,2)),
stringr::str_to_title(substr(X[2:length(X)],1,1))
),collapse="")
}))
FS1<-terra::aggregate(FarmSys[,c("LEV1_DESC")],"LEV1_DESC")
FS1<-terra::rasterize(FS1,BaseRaster,"LEV1_DESC",fun="near")
FS2<-terra::rasterize(FarmSys[,c("LEV2_DESC")],BaseRaster,"LEV2_DESC",fun=getmode)
FS_Metadata<-terra::values(FarmSys)
terra::writeRaster(FS1,filename="Data/Farming_systems/FS1.tif",overwrite=T)
terra::writeRaster(FS2,filename="Data/Farming_systems/FS2.tif",overwrite=T)
data.table::fwrite(FS_Metadata,file="Data/Farming_systems/FS_Metadata.csv")
}else{
FS1<-terra::rast("Data/Farming_systems/FS1.tif")
FS2<-terra::rast("Data/Farming_systems/FS2.tif")
FS_Metadata<-data.table::fread("Data/Farming_systems/FS_Metadata.csv")
}
```
```{r Farming Systems - GPLS, echo=F,eval=T}
# GLPS
GPLS_Legend<-data.table::fread("Data/GLPS/LPS_legend_RGB.csv")
GPLS_Legend$Code<-0:14
colnames(GPLS_Legend)[1]<-"ID"
LPS<-terra::crop(terra::resample(terra::rast("Data/GLPS/glps_gleam_61113_10km.tif"),BaseRaster,method="near"),CGIAR_countries)
LPS<-terra::mask(LPS,CGIAR_countries)
LPS<-LPS-1
LPS<-terra::categories(LPS,layer=1,value=GPLS_Legend,index=9)
```
:::: {style="display: flex;"}
::: {}
```{r Farming System - Choose classification, echo=F}
selectInput(inputId="FS_Choice",
label= "Classification",
choices = c("GLPS","Adaptation Atlas L1","Adaptation Atlas L2"),
selected = c("GLPS"),
multiple = F,
width="200px")
FS_Selected<-reactive({
if(input$FS_Choice=="GLPS"){
LPS
}else{
if(input$FS_Choice=="Adaptation Atlas L1"){
FS1
}else{
FS2
}
}
})
```
:::
:::{}
```{r Farming System - Choose Systems, echo=F}
FS_Options<-reactive({
FS_Options_Fun(FS_Selected=FS_Selected(),
ExtractBy.All=ExtractBy.All())
})
renderUI({
checkboxGroupInput(inputId="FS_Systems",
label= NULL,
choices = FS_Options(),
selected = FS_Options()[!FS_Options() %in% c("Urban","Unsuitable")],
inline = T)
})
```
:::
::::
**Crops (MapSPAM)**
:::: {style="display: flex;"}
::: {}
```{r Crops - Choose MapSPAM technology}
MS_options<-data.table::fread("Data/MapSPAM/MS Files.csv")
selectInput(inputId="MSTech",
label= "Technology",
choices = MS_options[,sort(unique(Tech))],
selected = c("all technologies"),
multiple = F,
width="200px")
MSTechCode<-reactive({MS_options[Tech==input$MSTech,unique(TechCode)]})
```
:::
:::{}
```{r Crops - Choose MapSPAM area type}
selectInput(inputId="MSAreaType",
label= "Area type",
choices = c("physical","harvested"),
selected = c("harvested"),
multiple = F,
width="200px")
```
:::
:::{}
```{r Extraction - Include totals,echo=F}
selectInput(inputId="IncTot",
label= "Extract totals?",
choices = c("Yes","No"),
selected = c("No"),
multiple = F,
width="150px")
```
:::
::::
```{r Crop - Choose crops}
renderUI({
checkboxGroupInput(inputId="CropChoice",
label= NULL,
choices = MS_options[TechCode==MSTechCode(),sort(unique(Crop))],
selected = c("maize","bean","cassava"),
inline = T)
})
```
**Livestock**
```{r Livestock - Choose systems}
LSvop_options<-data.table::fread("Data/Herrero/LS Files.csv")
checkboxGroupInput(inputId="LSChoice",
label= NULL,
choices = LSvop_options[,sort(unique(System))],
selected = c("Bovine meat"),
inline = T)
```
#### Countries
```{r Datasets - Crop base raster,echo=F}
BaseRaster<-terra::crop(BaseRaster,CGIAR_countries)
CellSize.km<-terra::cellSize(BaseRaster,mask=T, unit="km")
CellSize.ha<-terra::cellSize(BaseRaster,mask=T, unit="ha")
CountryRast<-terra::rasterize(CGIAR_countries,BaseRaster,"ADMIN")
CountryAreas<-data.table(
terra::zonal(
x=terra::cellSize(CountryRast,mask=T,unit="ha"),
z=CountryRast,
sum))
CGIAR_countries2<-reactive({
CGCountriesFun(CGIAR_countries=CGIAR_countries,
CountriesChoice=input$CountriesChoice,
SpillCountriesChoice=input$SpillCountriesChoice,
CoreColour=input$BorderColCore,
SpillColour=input$BorderColSpill)
})
AddBorders<-reactive({
function() {
terra::plot(CGIAR_countries2(),add=T,border=CGIAR_countries2()$Colour,lwd=input$borderwidth,lty=CGIAR_countries2()$Linetype)
}
})
```
```{r Datasets - plot CGIAR Countries, echo =F}
renderPlot({terra::plot(CGIAR_countries2(),
"Choice",
main="Selected countries",
border="black",
legend=input$LegPos,
type="classes",
pax=list(cex.axis=input$TextSize),
cex.main = input$TextSize*1.2,
axes = F,
frame.plot= F
)},
height=Plot.Height, width=Plot.Width)
```
#### Farming systems
[GLPC Livestock Production Systems (LPS) map](https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/WPDSZE) by [Robinson et al. 2014](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0096084)
The Adaptation L1 and L2 classifications are an adaption of [Dixon, John A., David P. Gibbon, and Aidan Gulliver. Farming systems and poverty: improving farmers' livelihoods in a changing world. Food & Agriculture Org., 2001](https://dataverse.harvard.edu/file.xhtml?persistentId=doi:10.7910/DVN/G4TBLF/7RIFT5&version=5.0).
```{r Datasets - Subset farming system, echo = F}
# This code relates to the farming system section, but is deliberately place here as when placed in the farming systems section it seemed to only activate when that tab was selected by the user. This prevented any analysis from proceeding.
Farming_System<-reactive({
FSsub_Fun(FS=FS_Selected(),
Choice = input$FS_Systems,
Mask = ExtractBy.All())
})
```
```{r Datasets- Plot farming system, echo =F}
renderPlot({terra::plot(Farming_System(),
main=if(input$FS_Choice=="GLPS"){
"Livestock production systems"
}else{
if(input$FS_Choice=="Adaptation Atlas L1"){
"Farming systems level 1"
}else{
"Farming systems level 2"
}},
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=nrow(levels(Farming_System())[[1]]),
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
axes = F,
legend = input$LegPos,
frame.plot= F)
terra::plot(CGIAR_countries2(),add=T,border=CGIAR_countries2()$Colour,lwd=input$borderwidth,lty=CGIAR_countries2()$Linetype)
},height=Plot.Height, width=Plot.Width)
```
#### Crops (MapSPAM) {.tabset .tabset-fade .tabset-pills}
MapSPAM datasets are used for crop value of production (VoP), Yield, Total Production and Area and can be downloaded [here](https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/FSSKBW) and methods reviewed [here](https://www.mapspam.info/methodology/).
**MapSPAM technology descriptions:**
* **all technologies** = all technologies together, ie complete crop or crop group.
* **irrigated** = refers to the crop area equipped with either full or partial control irrigation. Normally the crop production on the irrigated fields uses a high level of inputs such as modern varieties and fertilizer as well as advanced management such as soil/water conservation measures.
* **rainfed all** = rainfed portion of crop or crop group (= all technologies - irrigated).
* **rainfed high** = rainfed-based, uses high-yield varieties and some animal traction and mechanization. It at least applies some fertilizer, chemical pest, disease or weed controls and most of the product is produced for the market.
* **rainfed low** = rainfed crop production which uses traditional varieties and mainly manual labor without (or with little) application of nutrients or chemicals for pest and disease control. Production is mostly for their own consumption.
* **rainfed subsistence** = rainfed, low-input/subsistence production was introduced to account for situations where cropland and suitable areas do not exist, but farmland is still present in some way.
The definition of these production systems (management levels) more or less follows [FAO/IIASA’s GAEZ](http://www.iiasa.ac.at/Research/LUC/GAEZ/index.htm) project since SPAM uses its suitability surfaces.
**MapSPAM area type descriptions:**
* **Physical** = Physical area is measured in a hectare and represents the actual area where a crop is grown, not counting how often production was harvested from it. Physical area is calculated for each production system and crop, and the sum of all physical areas of the four production systems constitute the total physical area for that crop. The sum of the physical areas of all crops in a pixel may not be larger than the pixel size.
* **Harvested** = Harvested area is measured in a hectare, harvested area is at least as large as physical area, but sometimes more, since it also accounts for multiple harvests of a crop on the same plot. Like for physical area, the harvested area is calculated for each production system and the sum of all harvested areas of all production systems in a pixel amount to the total harvested area of the pixel. The sum of all the harvested areas of the crops in a pixel can be larger than the pixel size.
Citation: *International Food Policy Research Institute, 2020, "Spatially-Disaggregated Crop Production Statistics Data in Africa South of the Sahara for 2017", https://doi.org/10.7910/DVN/FSSKBW, Harvard Dataverse, V3*
##### Value of Production (VoP)
*SPAM’s cross entropy starts with prior knowledge of where crops may be grown and to which extent. It assumes that farmers, given a choice of different crops, will grow those which generate more revenue, this is where crop prices come in. SPAM uses a different price for every crop, but the same price for all countries: 2004-2006 average international price, as used by FAO to compute Value of Production.*
Download VoP [here](https://dataverse.harvard.edu/file.xhtml?fileId=4271679&version=3.0).
```{r Datasets - Load MapSPAM VoP,echo=F}
MSvop<-reactive({
if(!is.null(input$CropChoice)){
MSfun(VAR="VOP",
TECH=MSTechCode(),
CROPS=input$CropChoice,
BaseRaster=BaseRaster,
MASK=Farming_System(),
MS_options=MS_options,
Name="_vop",
IncTot=input$IncTot)
}else{
NA
}
})
```
**MapSPAM Crop Value of Production USD/pixel**
```{r Datasets - Plot MSvop, echo =F,error=F,warning=F}
renderPlot({terra::plot(if(input$log_plots=="Yes"){log(MSvop())}else{MSvop()},
fun=AddBorders(),
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
legend = input$LegPos,
axes = F,
frame.plot= F)
},height=Plot.Height, width=Plot.Width)
```
##### Area
**Physical area** *is measured in a hectare and represents the actual area where a crop is grown, not counting how often production was harvested from it. Physical area is calculated for each production system and crop, and the sum of all physical areas of the four production systems constitute the total physical area for that crop. The sum of the physical areas of all crops in a pixel may not be larger than the pixel size.*
Download crop physical area [here](https://dataverse.harvard.edu/file.xhtml?fileId=4271676&version=3.0).
**Harvested area** *is also measured in a hectare, and is at least as large as physical area, but sometimes more, since it also accounts for multiple harvests of a crop on the same plot. Like for physical area, the harvested area is calculated for each production system and the sum of all harvested areas of all production systems in a pixel amount to the total harvested area of the pixel. The sum of all the harvested areas of the crops in a pixel can be larger than the pixel size.*
Download crop harvested area [here](https://dataverse.harvard.edu/file.xhtml?fileId=4271688&version=3.0).
```{r Datasets - MapSPAM physical area, echo=F}
MShparea<-reactive({
if(!is.null(input$CropChoice)){
MSfun(VAR="PhysArea",
TECH=MSTechCode(),
CROPS=input$CropChoice,
BaseRaster=BaseRaster,
MASK=Farming_System(),
MS_options=MS_options,
Name="_area",
IncTot=input$IncTot)
}else{
NA
}
})
```
```{r Datasets - MapSPAM harvested area, echo=F}
MSharea<-reactive({
if(!is.null(input$CropChoice)){
MSfun(VAR="HarvArea",
TECH=MSTechCode(),
CROPS=input$CropChoice,
BaseRaster=BaseRaster,
MASK=Farming_System(),
MS_options=MS_options,
Name="_area",
IncTot=input$IncTot)
}else{
NA
}
})
```
```{r Set Area Type to be used in analysis,echo=F}
MSarea<-reactive({
if(!is.null(input$CropChoice)){
if(input$MSAreaType=="Physical"){
MShparea()
}else{
MSharea()
}
}else{
NA
}
})
```
**MapSPAM crop physical area - ha/pixel**
```{r Datasets - Plot MShparea, echo = F,error=F,warning=F}
renderPlot({
if(!is.null(input$CropChoice)){
terra::plot(if(input$log_plots=="Yes"){log(MShparea())}else{MShparea()},
fun=AddBorders(),
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
legend = input$LegPos,
axes = F,
frame.plot= F)
terra::plot(CGIAR_countries,add=T,border=input$BorderCol)
}
},height=Plot.Height, width=Plot.Width)
```
**MapSPAM crop harvested area - ha/pixel**
```{r Datasets - Plot MSharea, echo = F,error=F,warning=F}
renderPlot({
if(!is.null(input$CropChoice)){
terra::plot(if(input$log_plots=="Yes"){log(MSharea())}else{MSharea()},
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
legend = input$LegPos,
axes = F,
frame.plot= F)
terra::plot(CGIAR_countries,add=T,border=input$BorderCol)
}
},height=Plot.Height, width=Plot.Width)
```
##### Production
**Production** *, for each production system and crop, is calculated by multiplying area harvested with yield. It is measured in metric tons. The total production of a crop includes the production of all production systems of that crop.*
Download crop production volume [here](https://dataverse.harvard.edu/file.xhtml?fileId=4271677&version=3.0).
```{r Datasets - MapSPAM crop production, echo=F}
MSprod<-reactive({
if(!is.null(input$CropChoice)){
MSfun(VAR="Production",
TECH=MSTechCode(),
CROPS=input$CropChoice,
BaseRaster=BaseRaster,
MASK=Farming_System(),
MS_options=MS_options,
Name="_prod",
IncTot=input$IncTot)
}else{
NA
}
})
```
**MapSPAM Production - ton/pixel**
```{r Datasets - Plot MSprod, echo = F,error=F,warning=F}
renderPlot({
if(!is.null(input$CropChoice)){
terra::plot(if(input$log_plots=="Yes"){log(MSprod())}else{MSprod()},
fun=AddBorders(),
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
legend = input$LegPos,
axes = F,
frame.plot= F)
terra::plot(CGIAR_countries,add=T,border=input$BorderCol)
}
},height=Plot.Height, width=Plot.Width)
```
*Yield is a measure of productivity, the amount of production per harvested area, and is measured in kilogram/hectare. The total yield of a crop, when considering all production systems, is not the sum of the individual yields, but the weighted average of the 4 yields. Note that we do not directly extract yield from MapSPAM rasters in this analysis, rather we calculate by dividing production by harvested area.*
#### Livestock {.tabset .tabset-fade .tabset-pills}
These datasets come from [Herrero et al. 2013](https://www.pnas.org/doi/abs/10.1073/pnas.1308149110) in particular see the [supporting information](https://www.pnas.org/doi/suppl/10.1073/pnas.1308149110/suppl_file/sapp.pdf) for a detailed explanation of their methods.
Livestock VoP (as for crops) was calculated as production (t) times price ($/t). In the PNAS dataset, one international (global) price was used for each commodity for comparability, and these were 2005 dollars (Phil Thorton *pers comms*).
##### Value of production (VoP)
```{r Datasets - Load LSvop,echo=F}
# *CellSize.km to convert from USD/km2/year to USD/pixel/year
LSvop1<-reactive({
if(!is.null(input$LSChoice)){
terra::mask(terra::crop(
terra::rast(paste0("Data/Herrero/Resampled/",LSvop_options[System %in% input$LSChoice & Variable=="VOP",Filename]))*CellSize.km
,Farming_System()),Farming_System())
}else{
NA
}
})
```
```{r Datasets - LS rename and add totals, echo=F}
# Rename layers
LSvop<-reactive({
if(!is.null(input$LSChoice)){
LSfun(Data=LSvop1(),Choice=input$LSChoice,Extension="_vop",TotalName="LS",IncTot=input$IncTot)
}else{
NA
}
})
```
**Value of livestock production USD/pixel**
```{r Datasets - Plot LSvop, echo =F,error=F}
renderPlot({
if(!is.null(input$LSChoice)){
terra::plot(if(input$log_plots=="Yes"){log(LSvop())}else{LSvop()},
fun=AddBorders(),
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
axes = F,
frame.plot= F)
}
},height=Plot.Height, width=Plot.Width)
```
##### Yield & production
*Yield units are converted from kg/km2/year to t/km2/year*
```{r Datasets - Load LSyield,echo=F}
# Divide by 1000 to convert kg to t
LSyield<-reactive({
if(!is.null(input$LSChoice)){
terra::mask(
terra::crop(
terra::rast(paste0("Data/Herrero/Resampled/",LSvop_options[System %in% input$LSChoice & Variable=="MeatYield",Filename]))/1000,
Farming_System()),
Farming_System())
}else{
NA
}
})
# *CellSize.km converts yield t/km2/year to production per pixel t/pixel/year
LSprod2<-reactive({
if(!is.null(input$LSChoice)){
terra::mask(terra::crop(
terra::rast(paste0("Data/Herrero/Resampled/",LSvop_options[System %in% input$LSChoice & Variable=="MeatYield",Filename]))/1000*CellSize.km
,Farming_System()),Farming_System())
}else{
NA
}
})
# Rename layers
LSprod<-reactive({
if(!is.null(input$LSChoice)){
LSfun(Data=LSprod2(),Choice=input$LSChoice,Extension="_prod",TotalName="LS",IncTot=input$IncTot)
}else{
NA
}
})
```
**Livestock production t/pixel**
```{r Datasets - Plot LSprod, echo =F,error=F,warning=F}
renderPlot({
if(!is.null(input$LSChoice)){
terra::plot(if(input$log_plots=="Yes"){log(LSprod())}else{LSprod()},
fun=AddBorders(),
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
legend = input$LegPos,
axes = F,
frame.plot= F)
}
},height=Plot.Height, width=Plot.Width)
```
**Livestock yield t/ha**
```{r Datasets - Plot LSyield, echo =F,error=F,warning=F}
renderPlot({
if(!is.null(input$LSChoice)){
terra::plot(if(input$log_plots=="Yes"){log(LSyield())}else{LSyield()},
fun=AddBorders(),
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
axes = F,
frame.plot= F)
}
},height=Plot.Height, width=Plot.Width)
```
##### LS Area
*Note that we do not have a layer for this data so cellsize is currently substituted.*
```{r Datasets - Load LSarea,echo=F}
LSarea1<-reactive({
if(!is.null(input$LSChoice)){
LSareaFun(Data=LSprod())
}else{
NA
}
})
# Rename layers
LSarea<-reactive({
if(!is.null(input$LSChoice)){
LSfun(Data=LSarea1(),Choice=input$LSChoice,Extension="_area",TotalName="LS",IncTot=input$IncTot)
}else{
NA
}
})
```
**Livestock area (pixel size, ha)**
```{r Datasets - Plot LSarea, echo =F,error=F,warning=F}
renderPlot({
if(!is.null(input$LSChoice)){
terra::plot(LSarea(),
fun=AddBorders(),
pax=list(cex.axis=input$TextSize),
plg=list(x=input$LegPos,cex = input$TextSize,ncol=input$LegCols),
col=viridis(n=20,
option =input$Palette,
direction = if(input$Palette=="turbo"){1}else{-1}),
cex.main = input$TextSize*1.2,
lengend = input$LegPos,
axes = F,
frame.plot= F)
}
},height=Plot.Height, width=Plot.Width)
```
#### FAOSTAT{.tabset .tabset-fade .tabset-pills}
FAO data are used to estimate the national level variation in crop production over time. They are downloaded using the [FAOSTAT::get_faostat_bulk](https://search.r-project.org/CRAN/refmans/FAOSTAT/html/download_faostat_bulk.html) function. Data can also be accessed from the [FAOSTAT website](https://www.fao.org/faostat/en/#data/QCL) and directly downloaded [here](https://fenixservices.fao.org/faostat/static/bulkdownloads/Production_Crops_Livestock_E_All_Data_(Normalized).zip).
##### Prepare data
```{r Datasets - Load FAOSTAT, echo=T}
FAODir<-"Data/FAO"
FAOFile<-paste0(FAODir,"/FAO_prod.RData")
if(!file.exists(FAOFile)){
if(!dir.exists(FAODir)){
dir.create(FAODir)
}
fao_metadata<-FAOSTAT::FAOsearch()
#FAOSTAT::FAOsearch(dataset="crop",full=FALSE)
FAO_prod<-data.table(FAOSTAT::get_faostat_bulk(code="QCL",data_folder=FAODir))
UpdateFAOCountries<-data.table(
FAO=c("Bolivia (Plurinational State of)","Iran (Islamic Republic of)","Syrian Arab Republic","Congo","Viet Nam","Lao People's Democratic Republic","Côte d'Ivoire","Timor-Leste","Brunei Darussalam","Eswatini","Venezuela (Bolivarian Republic of)","Bahamas","United Republic of Tanzania"),
CGIAR=c("Bolivia","Iran","Syria","Republic of the Congo","Vietnam","Laos","Cote d'Ivoire","East Timor","Brunei","eSwatini","Venezuela","The Bahamas","Tanzania")
)
# Match then update FAO names with CGIAR names
N<-match(FAO_prod[,area],UpdateFAOCountries[,FAO])
FAO_prod[which(!is.na(N)),area:=UpdateFAOCountries[N[!is.na(N)],CGIAR]]
FAO_prod<-FAO_prod[area %in% CGIAR_countries$ADMIN]
save(FAO_prod,file=FAOFile)
# Remove downloaded zip file
unlink("Data/FAO/Production_Crops_Livestock_E_All_Data_(Normalized).zip")
}else{
FAO_prod<-miceadds::load.Rdata2(FAOFile)
}
FAO_prod<-FAO_prod[element %in% c("yield","milk_animals","yield_carcass_weight") & !is.na(value) & year %in% 2001:2020]
# Convert hg/ha to t/ha
FAO_prod[,value:=as.numeric(value)
][unit=="hg/ha",value:=value*0.0001
][unit=="hg/ha",unit:="t/ha"]
```
**Calculate coefficient of variation**
```{r Datasets - FAOSTAT calculate CV,echo=T}
FAO_CV<-FAO_prod[,list(Mean=mean(value),
SD=sd(value),
CV=100*(sd(value)/mean(value)),
N.Years=.N),by=list(area,item,element,unit)]
```
```{r Datasets - Map FAO names to MapSPAM,echo=T}
#Map FAO names to MapSPAM
MSCrops<-MS_options[,unique(Crop)]
FAOCrops<-FAO_CV[,tolower(unique(item))]
CropMatch<-MSCrops[MSCrops %in% FAOCrops]
CropNoMatch<-MSCrops[!MSCrops %in% FAOCrops]
CropMappings<-data.table(MapSPAM=MSCrops,FAO=as.character(NA))
CropMappings[MapSPAM %in% FAOCrops,FAO:=MapSPAM]
CropMappings[MapSPAM=="arabica coffee",FAO:="coffee, green"]
CropMappings[MapSPAM=="banana",FAO:="bananas"]
CropMappings[MapSPAM=="bean",FAO:="beans, dry"]
CropMappings[MapSPAM=="chickpea",FAO:="chick peas"]
CropMappings[MapSPAM=="coconut",FAO:="coconuts"]
CropMappings[MapSPAM=="cocoa",FAO:="cocoa, beans"]
CropMappings[MapSPAM=="cotton",FAO:="seed cotton"]
CropMappings[MapSPAM=="cowpea",FAO:="cow peas, dry" ]
CropMappings[MapSPAM=="groundnut",FAO:="groundnuts, with shell"]
CropMappings[MapSPAM=="lentil",FAO:="lentils"]
CropMappings[MapSPAM=="other cereals",FAO:="cereals nes"]
CropMappings[MapSPAM=="other fibre crops",FAO:="fibre crops nes"]
CropMappings[MapSPAM=="oilpalm",FAO:="oil palm fruit"]
CropMappings[MapSPAM=="other oil crops",FAO:="oilseeds nes"]
CropMappings[MapSPAM=="other pulses",FAO:="pulses nes"]
CropMappings[MapSPAM=="other roots",FAO:="roots and tubers nes"]
CropMappings[MapSPAM=="pigeonpea",FAO:="pigeons peas"]
CropMappings[MapSPAM=="plantain",FAO:="plantains and others"]
CropMappings[MapSPAM=="pearl millet",FAO:="millet"]
CropMappings[MapSPAM=="potato",FAO:="potatoes"]
CropMappings[MapSPAM=="robusta coffee",FAO:=NA]
CropMappings[MapSPAM=="rest of crops",FAO:=NA]
CropMappings[MapSPAM=="rice",FAO:="rice, paddy"]
CropMappings[MapSPAM=="sesameseed",FAO:="sesame seed"]
CropMappings[MapSPAM=="small millet",FAO:=NA]
CropMappings[MapSPAM=="soybean",FAO:="soybeans"]
CropMappings[MapSPAM=="sugarbeet",FAO:="sugar beet"]
CropMappings[MapSPAM=="sugarcane",FAO:="sugar cane"]
CropMappings[MapSPAM=="sunflower",FAO:="sunflower seed"]
CropMappings[MapSPAM=="sweet potato",FAO:="sweet potatoes"]
CropMappings[MapSPAM=="temperate fruit",FAO:=NA]
CropMappings[MapSPAM=="tropical fruit",FAO:="fruit, tropical fresh nes"]
CropMappings[MapSPAM=="vegetables",FAO:="vegetables primary"]
CropMappings[MapSPAM=="tobacco",FAO:="tobacco, unmanufactured"]
FAO_CV[,SpamName:=CropMappings[match(tolower(FAO_CV$item),CropMappings$FAO),MapSPAM]]
FAO_CV<-FAO_CV[!is.na(SpamName)]
FAO_prod[,SpamName:=CropMappings[match(tolower(FAO_prod$item),CropMappings$FAO),MapSPAM]]
FAO_prod<-FAO_prod[!is.na(SpamName)]
```
##### Raw data
To interpret these data please see the meta-data section under `Crops and livestock products` in this [FAOSTAT website](https://www.fao.org/faostat/en/#data/QCL) and this [pdf](https://fenixservices.fao.org/faostat/static/documents/Default_coding_and_flags.pdf). The `SpamName` field converts the FAO crop name in the `item` column to the corresponding SPAM name.
```{r Datasets - FAOSTAT DT Raw, echo=F}
renderDT({
datatable(dplyr::mutate_if(FAO_prod,is.numeric,~round(.,3)),
caption="",
extensions = 'Buttons',
filter = "top",
options = list(dom = 'Blfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print'),
lengthMenu = list(c(10,25,50,-1),c(10,25,50,"All"))))
})
```
##### Coefficent of variation (CV)
For a national time series of crop yields CV is calculated as `100*(sd(crop_yield)/mean(crop_yield))`.