Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated RCS, formatted Stata, added SPSS, R and Python #178

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#------------------------------------------------------------------------------
# WFP Standardized Scripts
# Resilience Capacity Score (RCS) Calculation
#------------------------------------------------------------------------------

# The RCS is calculated from 9 sub-statements using a five-point Likert scale
# (ranging from 'strongly disagree' to 'strongly agree') to capture the household
# perception of existing resilience capacities or livelihood capital.
# The Resilience Capacity Score aggregates the unweighted answers to the nine
# statements and is normalized to provide a score ranging from 0 to 100.
# This result is used to classify households in three groups (low, medium, or high).
# The percentages at each level are used later in following the changes over time
# in these percentages for a specific target group of households.
# Progress achieved or change over time in any of the 9 items is also calculated
# to understand which capacities or capitals contribute the most to the final score
# and which need to be reinforced to enhance future climate resilience.

library(tidyverse)
library(labelled)
library(expss)

# Load the data
data <- read_csv("path/to/RCS_Sample_Survey.csv")

# Label variables and values
var_label(data$HHRCSBounce) <- "Your household can bounce back from any challenge that life throws at it."
var_label(data$HHRCSRevenue) <- "During times of hardship your household can change its primary income or source of livelihood if needed."
var_label(data$HHRCSIncrease) <- "If threats to your household became more frequent and intense, you would still find a way to get by."
var_label(data$HHRCSFinAccess) <- "During times of hardship your household can access the financial support you need."
var_label(data$HHRCSSupportCommunity)<- "Your household can rely on the support of family or friends when you need help."
var_label(data$HHRCSLessonsLearnt) <- "Your household has learned important lessons from past hardships that will help you to better prepare for future challenges."
var_label(data$HHRCSSupportPublic) <- "Your household can rely on the support from public administration/government or other institutions when you need help."
var_label(data$HHRCSFutureChallenge) <- "Your household is fully prepared for any future challenges or threats that life throws at it."
var_label(data$HHRCSWarningAccess) <- "Your household receives useful information warning you about future risks in advance."

data <- data %>%
mutate(across(
c(HHRCSBounce, HHRCSRevenue, HHRCSIncrease, HHRCSFinAccess, HHRCSSupportCommunity, HHRCSSupportPublic, HHRCSLessonsLearnt, HHRCSFutureChallenge, HHRCSWarningAccess),
~labelled(., labels = c(
"Strongly Agree" = 1,
"Partially agree" = 2,
"Neutral" = 3,
"Somewhat disagree" = 4,
"Totally disagree" = 5
))
))

# Calculate the Resilience Capacity Score (RCS)
data <- data %>%
mutate(
RCS = (rowSums(across(c(HHRCSBounce, HHRCSRevenue, HHRCSIncrease, HHRCSFinAccess, HHRCSSupportCommunity, HHRCSSupportPublic, HHRCSLessonsLearnt, HHRCSFutureChallenge, HHRCSWarningAccess))) / 9 - 1) * (100 / 4)
)

var_label(data$RCS) <- "Resilience Capacity Score"

# Classify households into RCS categories
data <- data %>%
mutate(
RCSCat33 = case_when(
RCS < 33 ~ 1,
RCS < 66 ~ 2,
TRUE ~ 3
)
)

var_label(data$RCSCat33) <- "RCS Categories, thresholds 33-66"
val_lab(data$RCSCat33) = num_lab("
1 low RCS
2 medium RCS
3 high RCS
")

# Calculate RCS components
data <- data %>%
mutate(
RCSAnticipatory = (HHRCSFutureChallenge - 1) * (100 / 4),
RCSAbsorptive = (HHRCSBounce - 1) * (100 / 4),
RCSTransformative = (HHRCSRevenue - 1) * (100 / 4),
RCSAdaptive = (HHRCSIncrease - 1) * (100 / 4)
)

data <- data %>%
mutate(
RCSAnticipatoryCat33 = case_when(
RCSAnticipatory < 33 ~ 1,
RCSAnticipatory < 66 ~ 2,
TRUE ~ 3
),
RCSAbsorptiveCat33 = case_when(
RCSAbsorptive < 33 ~ 1,
RCSAbsorptive < 66 ~ 2,
TRUE ~ 3
),
RCSTransformativeCat33 = case_when(
RCSTransformative < 33 ~ 1,
RCSTransformative < 66 ~ 2,
TRUE ~ 3
),
RCSAdaptiveCat33 = case_when(
RCSAdaptive < 33 ~ 1,
RCSAdaptive < 66 ~ 2,
TRUE ~ 3
)
)

val_lab(data$RCSAnticipatoryCat33) = num_lab("
1 low
2 medium
3 high
")
val_lab(data$RCSAbsorptiveCat33) = num_lab("
1 low
2 medium
3 high
")
val_lab(data$RCSTransformativeCat33) = num_lab("
1 low
2 medium
3 high
")
val_lab(data$RCSAdaptiveCat33) = num_lab("
1 low
2 medium
3 high
")

# Create a table of results for COMET reporting
RCS_summary <- data %>%
group_by(RCSCat33) %>%
summarize(count = n()) %>%
mutate(percentage = count / sum(count) * 100)

write.csv(RCS_summary, "RCS_COMET.csv")

# End of Scripts
124 changes: 52 additions & 72 deletions Indicators/Resilience-capacity-score/RCS-indicator-calculation.do
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
/*
The RCS is calculated from 9 sub-statements using a five-point Likert scale (ranging from 'strongly disagree' to 'strongly agree') to capture the household perception of existing resilience capacities or livelihood capital.
The Resilience Capacity Score aggregates the unweighted answers to the nine statements and is normalized to provide a score ranging from 0 to 100.
This result is used to classify households in three groups (low, medium, or high). The percentages at each level are used later in following the changes over time in these percentages for a specific target group of households.
Progress achieved or change over time in any of the 9 items is also calculated to understand which capacities or capitals contribute the most to the final score and which need to be reinforced to enhance future climate resilience. */

*------------------------------------------------------------------------------
* WFP Standardized Scripts
* Resilience Capacity Score (RCS) Calculation
*------------------------------------------------------------------------------

* The RCS is calculated from 9 sub-statements using a five-point Likert scale
* (ranging from 'strongly disagree' to 'strongly agree') to capture the household
* perception of existing resilience capacities or livelihood capital.
* The Resilience Capacity Score aggregates the unweighted answers to the nine
* statements and is normalized to provide a score ranging from 0 to 100.
* This result is used to classify households in three groups (low, medium, or high).
* The percentages at each level are used later in following the changes over time
* in these percentages for a specific target group of households.
* Progress achieved or change over time in any of the 9 items is also calculated
* to understand which capacities or capitals contribute the most to the final score
* and which need to be reinforced to enhance future climate resilience.

* Load the data
import delim using "../../Static/RCS_Sample_Survey.csv", clear case(preserve) bindquotes(strict) varn(1)

* Destring variables if necessary
qui foreach var of varlist HHRCSBounce HHRCSRevenue HHRCSIncrease HHRCSFinAccess HHRCSSupportCommunity HHRCSSupportPublic HHRCSLessonsLearnt HHRCSFutureChallenge HHRCSWarningAccess {
cap destring `var', replace i("n/a")
cap destring `var', replace i("n/a")
}
/// GENERATE RANDOM DATA

* Generate random data (for testing purposes)
expand 100 in 4
generate w = runiform()

foreach var of varlist HHRCSBounce HHRCSRevenue HHRCSIncrease HHRCSFinAccess HHRCSSupportCommunity HHRCSSupportPublic HHRCSLessonsLearnt HHRCSFutureChallenge HHRCSWarningAccess {
replace w = runiform()
qui su w
replace `var'=round((w-r(min))*(5-1)/(r(max)-r(min)) + 1,1)

replace w = runiform()
qui su w
replace `var'=round((w-r(min))*(5-1)/(r(max)-r(min)) + 1,1)
}

//// END OF RANDOM DATA GENERATION
***Resilience Capacity Score***
capture confirm variable RCS
if !_rc {
cap rename RCS old_RCS
}
*
* Label variables and values
label var HHRCSBounce "Your household can bounce back from any challenge that life throws at it."
label var HHRCSRevenue "During times of hardship your household can change its primary income or source of livelihood if needed."
label var HHRCSIncrease "If threats to your household became more frequent and intense, you would still find a way to get by."
Expand All @@ -39,64 +47,42 @@ label var HHRCSWarningAccess "Your household receives useful information warn
label define Likert5 1 "Strongly Agree" 2 "Partially agree" 3 "Neutral" 4 "Somewhat disagree" 5 "Totally disagree"
label values HHRCSBounce HHRCSRevenue HHRCSIncrease HHRCSFinAccess HHRCSSupportCommunity HHRCSSupportPublic HHRCSLessonsLearnt HHRCSFutureChallenge HHRCSWarningAccess Likert5


** Standardizing the score. ***************************************************
/*
Once answers to each of the statements have been gathered, they are numerically converted (Strongly agree = 1, Agree=2, Neutral =3, Disagree=4, Strongly disagree = 5). Individual answers are then used to compute an overall resilience score for each household as an equally weighted average of the nine answers.

The resilience score is standardized by minmax normalization , transforming the results in a score that ranges from 0 (not at all resilient) to 100 (fully resilient).
y = (ymax-ymin)*(x-xmin)/(xmax-xmin) + ymin;
RCS=(100-0)*(RCS/9-5)/(1-5) + 0
*/
egen RCS= rowtotal(HHRCSBounce HHRCSRevenue HHRCSIncrease HHRCSFinAccess HHRCSSupportCommunity HHRCSSupportPublic HHRCSLessonsLearnt HHRCSFutureChallenge HHRCSWarningAccess)
replace RCS=(100-0)*((RCS/9)-5)/(1-5) + 0
* Calculate the Resilience Capacity Score (RCS)
egen RCS = rowtotal(HHRCSBounce HHRCSRevenue HHRCSIncrease HHRCSFinAccess HHRCSSupportCommunity HHRCSSupportPublic HHRCSLessonsLearnt HHRCSFutureChallenge HHRCSWarningAccess)
replace RCS = (100-0) * ((RCS/9) - 5) / (1-5) + 0
label var RCS "Resilience Capacity Score"

br RCS


/*
Once the RCS is calculated, households are divided in terciles (low-medium-high) to show the distribution of the RCS within the target population. Therefore:
if RCS<33 the household is categorized as reporting a low RCS,
if 33=<RCS<66 the household is categorized as reporting a medium RCS and
if RCS>=66 then the household is categorized as reporting a high RCS.
*/

gen RCSCat33=cond(RCS<33,1,cond(RCS<66,2,3))
* Classify households into RCS categories
gen RCSCat33 = cond(RCS < 33, 1, cond(RCS < 66, 2, 3))
label var RCSCat33 "RCS Categories, thresholds 33-66"
*** define variables labels and properties for "RCS Categories".
label define RCSCat 1 "low RCS" 2 "medium RCS" 3 "high RCS"
label define RCSCat2 1 "low" 2 "medium" 3 "high"

label values RCSCat33 RCSCat

*Once all households are categorized, counting the number of households in each tercile (low-medium-high) divided by the sample size (n) is the percentage to be reported in COMET.

*Steps a and b must be repeated with the first four statements separated.
*In other words, including only answers to statements S1 to S4 produce the scores of resilience capacities as follows:
gen RCSAnticipatory=(100-0)*(HHRCSFutureChallenge-5)/(1-5) + 0
gen RCSAbsorptive=(100-0)*(HHRCSBounce-5)/(1-5) + 0
gen RCSTransformative=(100-0)*(HHRCSRevenue-5)/(1-5) + 0
gen RCSAdaptive=(100-0)*(HHRCSIncrease-5)/(1-5) + 0
* Calculate RCS components
gen RCSAnticipatory = (100-0) * (HHRCSFutureChallenge - 5) / (1-5) + 0
gen RCSAbsorptive = (100-0) * (HHRCSBounce - 5) / (1-5) + 0
gen RCSTransformative = (100-0) * (HHRCSRevenue - 5) / (1-5) + 0
gen RCSAdaptive = (100-0) * (HHRCSIncrease - 5) / (1-5) + 0

gen RCSAnticipatoryCat33=cond(RCSAnticipatory<33,1,cond(RCSAnticipatory<66,2,3))
gen RCSAbsorptiveCat33=cond(RCSAbsorptive<33,1,cond(RCSAbsorptive<66,2,3))
gen RCSTransformativeCat33=cond(RCSTransformative<33,1,cond(RCSTransformative<66,2,3))
gen RCSSAdaptiveCat33=cond(RCSAdaptive<33,1,cond(RCSAdaptive<66,2,3))
gen RCSAnticipatoryCat33 = cond(RCSAnticipatory < 33, 1, cond(RCSAnticipatory < 66, 2, 3))
gen RCSAbsorptiveCat33 = cond(RCSAbsorptive < 33, 1, cond(RCSAbsorptive < 66, 2, 3))
gen RCSTransformativeCat33 = cond(RCSTransformative < 33, 1, cond(RCSTransformative < 66, 2, 3))
gen RCSAdaptiveCat33 = cond(RCSAdaptive < 33, 1, cond(RCSAdaptive < 66, 2, 3))
label values RCSAnticipatoryCat33 RCSAbsorptiveCat33 RCSTransformativeCat33 RCSAdaptiveCat33 RCSCat

label values RCSAnticipatoryCat33 RCSAbsorptiveCat33 RCSTransformativeCat33 RCSSAdaptiveCat33 RCSCat2
*** Let's now create the table of results needed in COMET reporting:
* Create the table of results needed in COMET reporting
tabulate RCSAnticipatoryCat33, matcell(freq1) matrow(names1)
tabulate RCSAbsorptiveCat33, matcell(freq2) matrow(names2)
tabulate RCSTransformativeCat33, matcell(freq3) matrow(names3)
tabulate RCSSAdaptiveCat33, matcell(freq4) matrow(names4)
tabulate RCSAdaptiveCat33, matcell(freq4) matrow(names4)
tabulate RCSCat33, matcell(freq5) matrow(names5)
matrix Anticipatory=freq1'/r(N)
matrix Absorptive=freq2'/r(N)
matrix Transformative=freq3'/r(N)
matrix Adaptive=freq4'/r(N)
matrix RCS=freq5'/r(N)
*All key results to be reported in COMET are shown in the following table:

matrix Anticipatory = freq1' / r(N)
matrix Absorptive = freq2' / r(N)
matrix Transformative = freq3' / r(N)
matrix Adaptive = freq4' / r(N)
matrix RCS = freq5' / r(N)

putexcel set "RCS_COMET.xlsx", replace
putexcel B1:D1, merge
putexcel A1=("RCS - Components") B1=("RCS Levels (percentages)") A3=("Anticipatory capacity") A4=("Absorptive capacity") A5=("Transformative capacity") A6=("Adaptive capacity") A7=("Resilience capacity")
Expand All @@ -106,11 +92,5 @@ putexcel B4=matrix(Absorptive), nformat("#.0 %")
putexcel B5=matrix(Transformative), nformat("#.0 %")
putexcel B6=matrix(Adaptive), nformat("#.0 %")
putexcel B7=matrix(RCS), nformat("#.0 %")
/*
As each figure represents the percentage of households at each level, the sum of each row must be 100% in all cases.
Individual statement score calculation:

The calculation of the average score for each statement is recommended for use in the narrative and in the further analysis of elements with higher incidence in the RCS calculation and/or for picking out the major variations over time of the elements of the score.

Therefore, using answers coded as values from 1 to 5, the sum of all values for each statement(S), divided by the sample size (n) will yield 9 values (one for each Q) that could be compared over time and used as shown in the visualization section.
*/
* End of Scripts
79 changes: 79 additions & 0 deletions Indicators/Resilience-capacity-score/RCS-indicator-calculation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#------------------------------------------------------------------------------
# WFP Standardized Scripts
# Resilience Capacity Score (RCS) Calculation
#------------------------------------------------------------------------------

# The RCS is calculated from 9 sub-statements using a five-point Likert scale
# (ranging from 'strongly disagree' to 'strongly agree') to capture the household
# perception of existing resilience capacities or livelihood capital.
# The Resilience Capacity Score aggregates the unweighted answers to the nine
# statements and is normalized to provide a score ranging from 0 to 100.
# This result is used to classify households in three groups (low, medium, or high).
# The percentages at each level are used later in following the changes over time
# in these percentages for a specific target group of households.
# Progress achieved or change over time in any of the 9 items is also calculated
# to understand which capacities or capitals contribute the most to the final score
# and which need to be reinforced to enhance future climate resilience.

import pandas as pd
import numpy as np

# Load the data
data = pd.read_csv("path/to/RCS_Sample_Survey.csv")

# Label variables and values
labels = {
'HHRCSBounce': "Your household can bounce back from any challenge that life throws at it.",
'HHRCSRevenue': "During times of hardship your household can change its primary income or source of livelihood if needed.",
'HHRCSIncrease': "If threats to your household became more frequent and intense, you would still find a way to get by.",
'HHRCSFinAccess': "During times of hardship your household can access the financial support you need.",
'HHRCSSupportCommunity': "Your household can rely on the support of family or friends when you need help.",
'HHRCSLessonsLearnt': "Your household has learned important lessons from past hardships that will help you to better prepare for future challenges.",
'HHRCSSupportPublic': "Your household can rely on the support from public administration/government or other institutions when you need help.",
'HHRCSFutureChallenge': "Your household is fully prepared for any future challenges or threats that life throws at it.",
'HHRCSWarningAccess': "Your household receives useful information warning you about future risks in advance."
}

likert_labels = {
1: "Strongly Agree",
2: "Partially agree",
3: "Neutral",
4: "Somewhat disagree",
5: "Totally disagree"
}

for col in labels.keys():
data[col] = data[col].astype(pd.CategoricalDtype(categories=likert_labels.keys(), ordered=True))
data[col].cat.rename_categories(likert_labels, inplace=True)

# Calculate the Resilience Capacity Score (RCS)
data['RCS'] = ((data[list(labels.keys())].apply(lambda x: x.cat.codes + 1).sum(axis=1) / 9 - 1) * (100 / 4)).astype(float)
data['RCS'].attrs['label'] = "Resilience Capacity Score"

# Classify households into RCS categories
data['RCSCat33'] = pd.cut(data['RCS'], bins=[-np.inf, 33, 66, np.inf], labels=[1, 2, 3])

data['RCSCat33'] = data['RCSCat33'].astype(int)
data['RCSCat33'] = data['RCSCat33'].replace({1: 'low RCS', 2: 'medium RCS', 3: 'high RCS'})
data['RCSCat33'].attrs['label'] = "RCS Categories, thresholds 33-66"

# Calculate RCS components
data['RCSAnticipatory'] = ((data['HHRCSFutureChallenge'].cat.codes + 1 - 1) * (100 / 4)).astype(float)
data['RCSAbsorptive'] = ((data['HHRCSBounce'].cat.codes + 1 - 1) * (100 / 4)).astype(float)
data['RCSTransformative'] = ((data['HHRCSRevenue'].cat.codes + 1 - 1) * (100 / 4)).astype(float)
data['RCSAdaptive'] = ((data['HHRCSIncrease'].cat.codes + 1 - 1) * (100 / 4)).astype(float)

data['RCSAnticipatoryCat33'] = pd.cut(data['RCSAnticipatory'], bins=[-np.inf, 33, 66, np.inf], labels=[1, 2, 3])
data['RCSAbsorptiveCat33'] = pd.cut(data['RCSAbsorptive'], bins=[-np.inf, 33, 66, np.inf], labels=[1, 2, 3])
data['RCSTransformativeCat33'] = pd.cut(data['RCSTransformative'], bins=[-np.inf, 33, 66, np.inf], labels=[1, 2, 3])
data['RCSAdaptiveCat33'] = pd.cut(data['RCSAdaptive'], bins=[-np.inf, 33, 66, np.inf], labels=[1, 2, 3])

# Create a table of results for COMET reporting
RCS_summary = data['RCSCat33'].value_counts(normalize=True).reset_index()
RCS_summary.columns = ['RCSCat33', 'Percentage']
RCS_summary['Percentage'] = RCS_summary['Percentage'] * 100

# Save to CSV
RCS_summary.to_csv("RCS_COMET.csv", index=False)

# End of Scripts
Loading