import%20marimo%0A%0A__generated_with%20%3D%20%220.23.4%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22%2C%20app_title%3D%22Grounds%20for%20Correlation%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Grounds%20for%20Correlation%0A%20%20%20%20%23%23%23%20Do%20climate%2C%20population%2C%20and%20oil%20price%20predict%20coffee%20bean%20production%20and%20export%20revenue%3F%0A%0A%20%20%20%20**INEG%202314H%20%E2%80%94%20Statistics%20for%20Industrial%20Engineers%20%7C%20Warren%20Ross**%0A%0A%20%20%20%20---%0A%0A%20%20%20%20This%20notebook%20walks%20through%20a%20complete%20exploratory%20statistical%20analysis%20of%20country-level%20coffee%0A%20%20%20%20production%20(1995%E2%80%932024).%20Four%20independent%20variables%20are%20tested%20against%20two%20response%20variables%3A%0A%0A%20%20%20%20%7C%20Variable%20%7C%20Role%20%7C%20Symbol%20%7C%0A%20%20%20%20%7C---%7C---%7C---%7C%0A%20%20%20%20%7C%20Average%20temperature%20(%C2%B0C)%20%7C%20Predictor%20%7C%20X%E2%82%81%20%7C%0A%20%20%20%20%7C%20Average%20rainfall%20(mm%2Fyr)%20%7C%20Predictor%20%7C%20X%E2%82%82%20%7C%0A%20%20%20%20%7C%20Annual%20population%20%7C%20Predictor%20%7C%20X%E2%82%83%20%7C%0A%20%20%20%20%7C%20Brent%20crude%20oil%20price%20(USD%2Fbbl)%20%7C%20Predictor%20%7C%20X%E2%82%84%20%7C%0A%20%20%20%20%7C%20Coffee%20production%20(tonnes)%20%7C%20**Response**%20%7C%20Y%E2%82%81%20%7C%0A%20%20%20%20%7C%20Export%20revenue%20(1000%20USD)%20%7C%20**Response**%20%7C%20Y%E2%82%82%20%7C%0A%0A%20%20%20%20**Predictors%20(X)**%20are%20the%20candidate%20explanatory%20variables%20%E2%80%94%20the%20factors%20we%20test%20as%20potential%20drivers%20of%20coffee%20output.%0A%20%20%20%20**Responses%20(Y)**%20are%20the%20outcomes%20we%20are%20trying%20to%20explain.%0A%20%20%20%20The%20notebook%20asks%3A%20does%20a%20country's%20temperature%2C%20rainfall%2C%20population%20size%2C%20or%20global%20oil%20price%20help%20explain%20how%20much%20coffee%20it%20produces%20and%20earns%20from%20exports%3F%0A%0A%20%20%20%20**Analysis%20window%3A**%201995%E2%80%932024%20%C2%B7%20**Countries%3A**%20~74%20coffee-producing%20nations%20(complete%20cases)%0A%0A%20%20%20%20%5BView%20source%20on%20GitHub%20%E2%86%92%5D(https%3A%2F%2Fgithub.com%2Fwarrenrross%2Fcoffee_bean_production_analysis)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%200%20%C2%B7%20Setup%20and%20Data%20Loading%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%3E%20**Panel%20data%3A**%20This%20analysis%20uses%20a%20*panel%20dataset*%20%E2%80%94%20one%20row%20per%20country%20per%20year%2C%0A%20%20%20%20%3E%20covering%201995%E2%80%932024.%20Unlike%20a%20single%20cross-section%20(one%20observation%20per%20country)%2C%20panel%20data%0A%20%20%20%20%3E%20has%20repeated%20observations%20for%20the%20same%20countries%20over%20time.%20This%20matters%20for%20interpretation%3A%0A%20%20%20%20%3E%20the%20regression%20captures%20patterns%20both%20*across%20countries*%20(wetter%20climates%20vs.%20drier%20ones)%20and%0A%20%20%20%20%3E%20*within%20countries%20over%20time*%20(years%20when%20production%20rose%20or%20fell).%20It%20also%20means%20observations%0A%20%20%20%20%3E%20are%20not%20independent%20%E2%80%94%20the%20same%20country%20appears%20in%20~30%20consecutive%20rows%20%E2%80%94%20which%20is%20why%20we%20use%0A%20%20%20%20%3E%20clustered%20standard%20errors%20in%20the%20robustness%20checks%20(%C2%A74.2).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20scipy.stats%20as%20stats%0A%20%20%20%20import%20statsmodels.formula.api%20as%20smf%0A%20%20%20%20import%20statsmodels.api%20as%20sm%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20matplotlib.ticker%20as%20mticker%0A%20%20%20%20import%20seaborn%20as%20sns%0A%20%20%20%20import%20warnings%0A%0A%20%20%20%20warnings.filterwarnings(%22ignore%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Plotting%20defaults%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20plt.rcParams.update(%7B%0A%20%20%20%20%20%20%20%20%22figure.dpi%22%3A%20130%2C%0A%20%20%20%20%20%20%20%20%22axes.spines.top%22%3A%20False%2C%0A%20%20%20%20%20%20%20%20%22axes.spines.right%22%3A%20False%2C%0A%20%20%20%20%20%20%20%20%22font.size%22%3A%2011%2C%0A%20%20%20%20%20%20%20%20%22axes.titlesize%22%3A%2013%2C%0A%20%20%20%20%20%20%20%20%22axes.titleweight%22%3A%20%22bold%22%2C%0A%20%20%20%20%7D)%0A%20%20%20%20ACCENT%20%20%20%3D%20%22%236F4E37%22%20%20%20%23%20coffee%20brown%0A%20%20%20%20ACCENT2%20%20%3D%20%22%232D6A4F%22%20%20%20%23%20forest%20green%0A%20%20%20%20GREY%20%20%20%20%20%3D%20%22%239E9E9E%22%0A%20%20%20%20return%20ACCENT%2C%20ACCENT2%2C%20mo%2C%20np%2C%20pd%2C%20plt%2C%20smf%2C%20sns%2C%20stats%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20pd)%3A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Load%20panel%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20%23%20Notebook%20lives%20at%20marimo%2Fcoffee_analysis.py%0A%20%20%20%20%23%20Data%20lives%20at%20data%2Fcoffee_analysis_panel_with_covariates.csv%20(relative%20to%20repo%20root)%0A%20%20%20%20import%20pathlib%0A%20%20%20%20_here%20%3D%20pathlib.Path(__file__).parent%20%20%20%20%20%20%20%20%20%20%23%20marimo%2F%0A%20%20%20%20DATA_PATH%20%3D%20_here.parent%20%2F%20%22data%22%20%2F%20%22coffee_analysis_panel_with_covariates.csv%22%0A%0A%20%20%20%20panel_raw%20%3D%20pd.read_csv(DATA_PATH)%0A%0A%20%20%20%20%23%20Rename%20Brent_Avg%20%E2%86%92%20Oil_Price_Brent_USD%20for%20clarity%20throughout%20the%20analysis%0A%20%20%20%20panel_raw%20%3D%20panel_raw.rename(columns%3D%7B%22Brent_Avg%22%3A%20%22Oil_Price_Brent_USD%22%7D)%0A%0A%20%20%20%20%23%20Drop%20rows%20missing%20any%20of%20the%20four%20predictors%20or%20either%20response%0A%20%20%20%20panel%20%3D%20panel_raw.dropna(subset%3D%5B%0A%20%20%20%20%20%20%20%20%22Production_tonnes%22%2C%20%22Export_Value_1000USD%22%2C%0A%20%20%20%20%20%20%20%20%22Avg_Temp_C%22%2C%20%22Rain_mm%22%2C%20%22Population%22%2C%20%22Oil_Price_Brent_USD%22%0A%20%20%20%20%5D).copy()%0A%0A%20%20%20%20%23%20Add%20log-transformed%20variables%20used%20in%20regression%0A%20%20%20%20panel%5B%22ln_Production%22%5D%20%20%20%20%3D%20np.log(panel%5B%22Production_tonnes%22%5D)%0A%20%20%20%20panel%5B%22ln_Export_Value%22%5D%20%20%3D%20np.log(panel%5B%22Export_Value_1000USD%22%5D)%0A%20%20%20%20panel%5B%22ln_Population%22%5D%20%20%20%20%3D%20np.log(panel%5B%22Population%22%5D)%0A%0A%20%20%20%20%23%20Rainfall%20decomposition%3A%20country%20mean%20(structural)%20vs%20within-country%20deviation%0A%20%20%20%20panel%5B%22Rain_mm_country_mean%22%5D%20%3D%20panel.groupby(%22ISO3%22)%5B%22Rain_mm%22%5D.transform(%22mean%22)%0A%20%20%20%20panel%5B%22Rain_mm_within%22%5D%20%20%20%20%20%20%20%3D%20panel%5B%22Rain_mm%22%5D%20-%20panel%5B%22Rain_mm_country_mean%22%5D%0A%0A%20%20%20%20print(f%22Panel%20loaded%3A%20%7Blen(panel)%3A%2C%7D%20rows%20%C2%B7%20%7Bpanel.ISO3.nunique()%7D%20countries%20%C2%B7%20%22%0A%20%20%20%20%20%20%20%20%20%20f%22%7Bpanel.Year.min()%7D%E2%80%93%7Bpanel.Year.max()%7D%22)%0A%20%20%20%20return%20(panel%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%3E%20**Complete-case%20filtering%3A**%20Rows%20missing%20any%20of%20the%20four%20predictors%20or%20either%20response%20variable%0A%20%20%20%20%3E%20are%20dropped%20before%20analysis.%20This%20complete-case%20approach%20simplifies%20interpretation%20but%20means%20the%0A%20%20%20%20%3E%20panel%20only%20includes%20country-years%20where%20all%20variables%20were%20observed.%20Countries%20or%20years%20with%0A%20%20%20%20%3E%20incomplete%20data%20are%20excluded%20entirely%2C%20which%20could%20affect%20conclusions%20if%20missingness%20is%20related%0A%20%20%20%20%3E%20to%20production%20levels.%0A%0A%20%20%20%20%3E%20**Why%20log-transform%3F%20(the%20mechanism)**%20A%20logarithm%20compresses%20very%20large%20values%20while%0A%20%20%20%20%3E%20spreading%20out%20small%20ones%20%E2%80%94%20ln(1%2C000%2C000)%20%3D%2013.8%2C%20but%20ln(1%2C000)%20%3D%206.9.%20This%20is%20useful%20when%0A%20%20%20%20%3E%20a%20variable%20spans%20several%20orders%20of%20magnitude%2C%20as%20coffee%20production%20does%20(from%20hundreds%20to%0A%20%20%20%20%3E%20millions%20of%20tonnes).%20It%20also%20converts%20*multiplicative*%20relationships%20into%20*additive*%20ones%3A%0A%20%20%20%20%3E%20if%20Brazil%20produces%2010%C3%97%20Vietnam's%20output%2C%20ln(Brazil)%20%E2%88%92%20ln(Vietnam)%20%3D%20ln(10)%20%E2%89%88%202.3%2C%20a%20constant%0A%20%20%20%20%3E%20gap.%20Linear%20regression%20handles%20additive%20relationships%20better%20than%20multiplicative%20ones.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%201%20%C2%B7%20Exploratory%20Data%20Analysis%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%201.1%20Descriptive%20Statistics%0A%0A%20%20%20%20**Right-skew%20in%20plain%20English%3A**%20A%20distribution%20is%20right-skewed%20when%20a%20few%20very%20large%20values%0A%20%20%20%20pull%20the%20tail%20to%20the%20right%20%E2%80%94%20most%20observations%20are%20smaller%2C%20but%20a%20handful%20are%20much%20larger.%0A%20%20%20%20Right-skew%20matters%20for%20regression%20because%20OLS%20assumes%20roughly%20symmetric%20residuals%3B%20a%20strongly%0A%20%20%20%20skewed%20response%20can%20produce%20biased-looking%20diagnostics%20even%20when%20the%20model%20is%20correctly%20specified.%0A%20%20%20%20The%20Skewness%20column%20below%20quantifies%20this%3A%20values%20above%201%20indicate%20notable%20right-skew.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20panel%2C%20pd)%3A%0A%20%20%20%20_vars%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22Production_tonnes%22%3A%20%20%20%20%20%20(%22Production%20(tonnes)%22%2C%20%20%20%20%20%20%20%20%22Y%E2%82%81%22)%2C%0A%20%20%20%20%20%20%20%20%22Export_Value_1000USD%22%3A%20%20%20(%22Export%20Revenue%20(1000%20USD)%22%2C%20%20%22Y%E2%82%82%22)%2C%0A%20%20%20%20%20%20%20%20%22Avg_Temp_C%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20(%22Avg%20Temperature%20(%C2%B0C)%22%2C%20%20%20%20%20%20%20%22X%E2%82%81%22)%2C%0A%20%20%20%20%20%20%20%20%22Rain_mm%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(%22Avg%20Rainfall%20(mm%2Fyr)%22%2C%20%20%20%20%20%20%20%22X%E2%82%82%22)%2C%0A%20%20%20%20%20%20%20%20%22Population%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20(%22Population%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22X%E2%82%83%22)%2C%0A%20%20%20%20%20%20%20%20%22Oil_Price_Brent_USD%22%3A%20%20%20%20(%22Brent%20Oil%20Price%20(USD%2Fbbl)%22%2C%20%20%22X%E2%82%84%22)%2C%0A%20%20%20%20%7D%0A%0A%20%20%20%20_rows%20%3D%20%5B%5D%0A%20%20%20%20for%20col%2C%20(label%2C%20role)%20in%20_vars.items()%3A%0A%20%20%20%20%20%20%20%20s%20%3D%20panel%5Bcol%5D%0A%20%20%20%20%20%20%20%20_rows.append(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Variable%22%3A%20label%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Role%22%3A%20role%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22n%22%3A%20len(s.dropna())%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Mean%22%3A%20s.mean()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Std%20Dev%22%3A%20s.std()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Min%22%3A%20s.min()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Median%22%3A%20s.median()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Max%22%3A%20s.max()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Skewness%22%3A%20s.skew()%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%0A%20%20%20%20desc%20%3D%20pd.DataFrame(_rows).set_index(%22Variable%22)%0A%0A%20%20%20%20%23%20Format%20nicely%0A%20%20%20%20def%20_fmt(val%2C%20col)%3A%0A%20%20%20%20%20%20%20%20if%20col%20in%20(%22n%22%2C)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20f%22%7Bint(val)%3A%2C%7D%22%0A%20%20%20%20%20%20%20%20if%20col%20%3D%3D%20%22Skewness%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20f%22%7Bval%3A.2f%7D%22%0A%20%20%20%20%20%20%20%20if%20abs(val)%20%3E%3D%201e6%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20f%22%7Bval%3A%2C.0f%7D%22%0A%20%20%20%20%20%20%20%20if%20abs(val)%20%3E%3D%201000%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20f%22%7Bval%3A%2C.1f%7D%22%0A%20%20%20%20%20%20%20%20return%20f%22%7Bval%3A.2f%7D%22%0A%0A%20%20%20%20desc_fmt%20%3D%20desc.copy()%0A%20%20%20%20for%20c%20in%20desc.columns%3A%0A%20%20%20%20%20%20%20%20if%20c%20!%3D%20%22Role%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20desc_fmt%5Bc%5D%20%3D%20desc%5Bc%5D.apply(lambda%20v%3A%20_fmt(v%2C%20c))%0A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%7Bmo.as_html(desc_fmt)%7D%0A%0A%20%20%20%20%20%20%20%20%3E%20**Note%20on%20skewness%3A**%20Production%20(skew%20%3D%20%7Bpanel%5B'Production_tonnes'%5D.skew()%3A.1f%7D)%20and%20Export%20Revenue%0A%20%20%20%20%20%20%20%20%3E%20(skew%20%3D%20%7Bpanel%5B'Export_Value_1000USD'%5D.skew()%3A.1f%7D)%20are%20strongly%20right-skewed.%20Log%20transformations%0A%20%20%20%20%20%20%20%20%3E%20are%20applied%20before%20regression%20and%20correlation%20analysis.%20Population%20(skew%20%3D%20%7Bpanel%5B'Population'%5D.skew()%3A.1f%7D)%0A%20%20%20%20%20%20%20%20%3E%20is%20also%20log-transformed%20due%20to%20its%20three-order-of-magnitude%20range.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%3E%20**Standard%20deviation%20vs.%20standard%20error%3A**%20The%20table%20above%20reports%20**Std%20Dev**%2C%20which%20describes%0A%20%20%20%20%3E%20the%20spread%20of%20the%20raw%20data%20%E2%80%94%20how%20much%20individual%20country-year%20values%20vary%20around%20the%20mean.%0A%20%20%20%20%3E%20Later%20regression%20tables%20report%20**Robust%20SE**%20(standard%20error%20of%20a%20coefficient)%2C%20which%20describes%0A%20%20%20%20%3E%20uncertainty%20in%20an%20*estimate*%20%E2%80%94%20how%20precisely%20the%20model%20has%20pinned%20down%20each%20%CE%B2%CC%82.%0A%20%20%20%20%3E%20These%20are%20different%20quantities%20and%20should%20not%20be%20compared%20directly.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%201.2%20Distributions%20%E2%80%94%20Production%20and%20Export%20Revenue%20(Raw%20vs.%20Log)%0A%0A%20%20%20%20**What%20a%20histogram%20shows%3A**%20Each%20bar%20counts%20how%20many%20observations%20fall%20in%20a%20range%20of%20values.%0A%20%20%20%20This%20is%20a%20*shape%20check*%2C%20not%20an%20inferential%20test.%20Look%20for%3A%20Is%20the%20distribution%20symmetric%20or%0A%20%20%20%20skewed%3F%20Are%20there%20long%20tails%3F%20Does%20the%20log-transformed%20version%20look%20more%20bell-shaped%3F%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ACCENT%2C%20ACCENT2%2C%20mo%2C%20panel%2C%20plt)%3A%0A%20%20%20%20def%20_()%3A%0A%20%20%20%20%20%20%20%20fig_dist%2C%20axes%20%3D%20plt.subplots(2%2C%202%2C%20figsize%3D(12%2C%208))%0A%20%20%20%20%20%20%20%20fig_dist.suptitle(%22Response%20Variable%20Distributions%3A%20Raw%20vs.%20Log-Transformed%22%2C%20fontsize%3D14%2C%20fontweight%3D%22bold%22)%0A%0A%20%20%20%20%20%20%20%20pairs%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(panel%5B%22Production_tonnes%22%5D%2C%20%20%20%22Production%20(tonnes)%22%2C%20%20%20%20%20%20%20%20ACCENT%2C%20%20axes%5B0%2C%200%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(panel%5B%22ln_Production%22%5D%2C%20%20%20%20%20%20%20%22ln(Production)%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%20ACCENT%2C%20%20axes%5B0%2C%201%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(panel%5B%22Export_Value_1000USD%22%5D%2C%22Export%20Revenue%20(1000%20USD)%22%2C%20%20ACCENT2%2C%20axes%5B1%2C%200%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(panel%5B%22ln_Export_Value%22%5D%2C%20%20%20%20%20%22ln(Export%20Revenue)%22%2C%20%20%20%20%20%20%20%20%20ACCENT2%2C%20axes%5B1%2C%201%5D)%2C%0A%20%20%20%20%20%20%20%20%5D%0A%0A%20%20%20%20%20%20%20%20for%20data%2C%20title%2C%20color%2C%20ax%20in%20pairs%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.hist(data.dropna()%2C%20bins%3D40%2C%20color%3Dcolor%2C%20alpha%3D0.8%2C%20edgecolor%3D%22white%22%2C%20linewidth%3D0.4)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(title)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel(%22Frequency%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20skew_val%20%3D%20data.skew()%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.annotate(f%22skew%20%3D%20%7Bskew_val%3A.2f%7D%22%2C%20xy%3D(0.97%2C%200.93)%2C%20xycoords%3D%22axes%20fraction%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ha%3D%22right%22%2C%20fontsize%3D9%2C%20color%3D%22%23555%22)%0A%0A%20%20%20%20%20%20%20%20%23%20Annotate%20the%20before%2Fafter%20logic%0A%20%20%20%20%20%20%20%20for%20col_idx%2C%20label%20in%20%5B(0%2C%20%22Before%20log%20transform%20%E2%86%92%22)%2C%20(1%2C%20%22%E2%86%90%20After%20log%20transform%22)%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20fig_dist.text(0.27%20%2B%20col_idx%20*%200.46%2C%200.02%2C%20label%2C%20ha%3D%22center%22%2C%20fontsize%3D9%2C%20color%3D%22%23777%22%2C%20style%3D%22italic%22)%0A%0A%20%20%20%20%20%20%20%20plt.tight_layout(rect%3D%5B0%2C%200.04%2C%201%2C%201%5D)%0A%20%20%20%20%20%20%20%20return%20mo.mpl.interactive(fig_dist)%0A%0A%0A%20%20%20%20_()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%3E%20**What%20this%20comparison%20shows%3A**%20The%20raw%20distributions%20are%20right-skewed%20%E2%80%94%20a%20few%20countries%20produce%0A%20%20%20%20%3E%20vastly%20more%20than%20most.%20The%20log-transformed%20versions%20are%20closer%20to%20symmetric.%20This%20matters%20because%0A%20%20%20%20%3E%20OLS%20regression%20performs%20better%20when%20the%20response%20variable%20is%20roughly%20symmetric%20%E2%80%94%20skewed%20responses%0A%20%20%20%20%3E%20can%20violate%20the%20normality-of-residuals%20assumption%20and%20make%20linear%20fits%20less%20stable.%0A%20%20%20%20%3E%20Log-transforming%20before%20regression%20is%20a%20model-building%20choice%2C%20not%20just%20a%20display%20convenience.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%201.3%20Global%20Production%20Time%20Series%20(1995%E2%80%932024)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ACCENT%2C%20mo%2C%20panel%2C%20plt)%3A%0A%20%20%20%20_global%20%3D%20(%0A%20%20%20%20%20%20%20%20panel.groupby(%22Year%22)%5B%22Production_tonnes%22%5D%0A%20%20%20%20%20%20%20%20.sum()%0A%20%20%20%20%20%20%20%20.reset_index()%0A%20%20%20%20)%0A%20%20%20%20_global%5B%22Production_million_t%22%5D%20%3D%20_global%5B%22Production_tonnes%22%5D%20%2F%201e6%0A%0A%20%20%20%20fig_ts%2C%20ax_ts%20%3D%20plt.subplots(figsize%3D(11%2C%204))%0A%20%20%20%20ax_ts.fill_between(_global%5B%22Year%22%5D%2C%20_global%5B%22Production_million_t%22%5D%2C%20alpha%3D0.18%2C%20color%3DACCENT)%0A%20%20%20%20ax_ts.plot(_global%5B%22Year%22%5D%2C%20_global%5B%22Production_million_t%22%5D%2C%20color%3DACCENT%2C%20linewidth%3D2.2%2C%20marker%3D%22o%22%2C%20markersize%3D4)%0A%20%20%20%20ax_ts.set_title(%22Global%20Coffee%20Production%20(Coffee-Producing%20Countries%20in%20Panel)%22%2C%20pad%3D10)%0A%20%20%20%20ax_ts.set_xlabel(%22Year%22)%0A%20%20%20%20ax_ts.set_ylabel(%22Production%20(million%20tonnes)%22)%0A%20%20%20%20ax_ts.set_xlim(1994%2C%202025)%0A%20%20%20%20ax_ts.yaxis.set_major_formatter(plt.FuncFormatter(lambda%20x%2C%20_%3A%20f%22%7Bx%3A.1f%7DM%20t%22))%0A%0A%20%20%20%20%23%20Annotate%20peak%20year%0A%20%20%20%20_peak%20%3D%20_global.loc%5B_global%5B%22Production_million_t%22%5D.idxmax()%5D%0A%20%20%20%20ax_ts.annotate(%0A%20%20%20%20%20%20%20%20f%22Peak%3A%20%7B_peak%5B'Production_million_t'%5D%3A.1f%7DM%20t%20(%7Bint(_peak%5B'Year'%5D)%7D)%22%2C%0A%20%20%20%20%20%20%20%20xy%3D(_peak%5B%22Year%22%5D%2C%20_peak%5B%22Production_million_t%22%5D)%2C%0A%20%20%20%20%20%20%20%20xytext%3D(-40%2C%2012)%2C%20textcoords%3D%22offset%20points%22%2C%0A%20%20%20%20%20%20%20%20arrowprops%3Ddict(arrowstyle%3D%22-%3E%22%2C%20color%3D%22%23555%22%2C%20lw%3D1.2)%2C%0A%20%20%20%20%20%20%20%20fontsize%3D9%2C%20color%3D%22%23333%22%0A%20%20%20%20)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20mo.mpl.interactive(fig_ts)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%3E%20**Descriptive%2C%20not%20inferential%3A**%20The%20upward%20trend%20in%20global%20production%20is%20visible%20in%20the%20plot%0A%20%20%20%20%3E%20above%2C%20but%20this%20chart%20alone%20does%20not%20test%20whether%20time%20causes%20production%20to%20grow.%20Establishing%0A%20%20%20%20%3E%20a%20significant%20time%20coefficient%20would%20require%20including%20%60Year%60%20as%20a%20predictor%20and%20testing%20its%0A%20%20%20%20%3E%20coefficient%20%E2%80%94%20which%20is%20done%20in%20the%20year-FE%20robustness%20check%20in%20%C2%A74.2.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%201.4%20Top%20Producers%20(2020)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ACCENT%2C%20mo%2C%20panel%2C%20plt)%3A%0A%20%20%20%20_top%20%3D%20(%0A%20%20%20%20%20%20%20%20panel%5Bpanel%5B%22Year%22%5D%20%3D%3D%202020%5D%0A%20%20%20%20%20%20%20%20.nlargest(12%2C%20%22Production_tonnes%22)%0A%20%20%20%20%20%20%20%20%5B%5B%22Country_Name%22%2C%20%22Production_tonnes%22%5D%5D%0A%20%20%20%20%20%20%20%20.copy()%0A%20%20%20%20)%0A%20%20%20%20_top%5B%22Production_million_t%22%5D%20%3D%20_top%5B%22Production_tonnes%22%5D%20%2F%201e6%0A%0A%20%20%20%20fig_top%2C%20ax_top%20%3D%20plt.subplots(figsize%3D(10%2C%204.5))%0A%20%20%20%20bars%20%3D%20ax_top.barh(_top%5B%22Country_Name%22%5D%5B%3A%3A-1%5D%2C%20_top%5B%22Production_million_t%22%5D%5B%3A%3A-1%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3DACCENT%2C%20alpha%3D0.85)%0A%20%20%20%20ax_top.set_title(%22Top%2012%20Coffee%20Producers%20%E2%80%94%202020%22%2C%20pad%3D10)%0A%20%20%20%20ax_top.set_xlabel(%22Production%20(million%20tonnes)%22)%0A%20%20%20%20ax_top.bar_label(bars%2C%20fmt%3D%22%25.2f%22%2C%20padding%3D4%2C%20fontsize%3D9)%0A%20%20%20%20ax_top.set_xlim(0%2C%20_top%5B%22Production_million_t%22%5D.max()%20*%201.18)%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20mo.mpl.interactive(fig_top)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%201.5%20Predictor%20vs.%20Response%20Scatter%20Plots%0A%0A%20%20%20%20*Pearson%20r%20is%20shown%20as%20an%20exploratory%20summary.%20Pooled%20p-values%20are%20omitted%20here%20%E2%80%94%20with%20n%20%E2%89%88%202%2C000%20panel%20rows%2C%20nearly%20every%20r%20is%20%22significant%22%20under%20i.i.d.%20assumptions.%20See%20%C2%A72%20for%20formal%20hypothesis%20tests.*%0A%0A%20%20%20%20**How%20to%20read%20a%20scatter%20plot%3A**%20look%20for%20four%20things%20%E2%80%94%20(1)%20**direction**%3A%20does%20the%20cloud%20slope%20upward%20or%20downward%3F%20(2)%20**tightness**%3A%20is%20the%20cloud%20compact%20or%20spread%20out%3F%20(3)%20**curvature**%3A%20does%20the%20relationship%20bend%20rather%20than%20follow%20a%20straight%20line%3F%20(4)%20**outliers**%3A%20are%20there%20points%20far%20from%20the%20main%20trend%3F%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ACCENT%2C%20ACCENT2%2C%20mo%2C%20np%2C%20panel%2C%20plt%2C%20stats)%3A%0A%20%20%20%20_predictors%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22Avg_Temp_C%22%2C%20%20%20%20%20%20%20%20%20%22Avg%20Temperature%20(%C2%B0C)%22%2C%20%20%20%20%20%20%20%22X%E2%82%81%22)%2C%0A%20%20%20%20%20%20%20%20(%22Rain_mm%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%22Avg%20Rainfall%20(mm%2Fyr)%22%2C%20%20%20%20%20%20%20%22X%E2%82%82%22)%2C%0A%20%20%20%20%20%20%20%20(%22ln_Population%22%2C%20%20%20%20%20%20%22ln(Population)%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%22ln(X%E2%82%83)%22)%2C%0A%20%20%20%20%20%20%20%20(%22Oil_Price_Brent_USD%22%2C%22Oil%20Price%20(USD%2Fbbl)%22%2C%20%20%20%20%20%20%20%20%22X%E2%82%84%22)%2C%0A%20%20%20%20%5D%0A%20%20%20%20_responses%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22ln_Production%22%2C%20%20%20%22ln(Production%2C%20tonnes)%22%2C%20%20%20%20ACCENT)%2C%0A%20%20%20%20%20%20%20%20(%22ln_Export_Value%22%2C%20%22ln(Export%20Revenue%2C%201000USD)%22%2C%20ACCENT2)%2C%0A%20%20%20%20%5D%0A%0A%20%20%20%20fig_scatter%2C%20axes_sc%20%3D%20plt.subplots(4%2C%202%2C%20figsize%3D(13%2C%2018))%0A%20%20%20%20fig_scatter.suptitle(%22Predictors%20vs.%20Response%20Variables%20(Log-Transformed%20Y)%22%2C%20fontsize%3D13%2C%20fontweight%3D%22bold%22%2C%20y%3D1.002)%0A%0A%20%20%20%20for%20row_idx%2C%20(pred_col%2C%20pred_label%2C%20pred_sym)%20in%20enumerate(_predictors)%3A%0A%20%20%20%20%20%20%20%20for%20col_idx%2C%20(resp_col%2C%20resp_label%2C%20color)%20in%20enumerate(_responses)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax%20%3D%20axes_sc%5Brow_idx%2C%20col_idx%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_d%20%3D%20panel%5B%5Bpred_col%2C%20resp_col%5D%5D.dropna()%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.scatter(_d%5Bpred_col%5D%2C%20_d%5Bresp_col%5D%2C%20alpha%3D0.25%2C%20s%3D14%2C%20color%3Dcolor%2C%20linewidths%3D0)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20OLS%20trend%20line%0A%20%20%20%20%20%20%20%20%20%20%20%20_m%2C%20_b%2C%20_r%2C%20_p%2C%20_%20%3D%20stats.linregress(_d%5Bpred_col%5D%2C%20_d%5Bresp_col%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20_x_line%20%3D%20np.linspace(_d%5Bpred_col%5D.min()%2C%20_d%5Bpred_col%5D.max()%2C%20200)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.plot(_x_line%2C%20_m%20*%20_x_line%20%2B%20_b%2C%20color%3D%22%23333%22%2C%20linewidth%3D1.5%2C%20linestyle%3D%22--%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(f%22%7Bpred_sym%7D%3A%20%7Bpred_label%7D%22%2C%20fontsize%3D9)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel(resp_label%2C%20fontsize%3D9)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.annotate(f%22r%20%3D%20%7B_r%3A.3f%7D%22%2C%20xy%3D(0.05%2C%200.93)%2C%20xycoords%3D%22axes%20fraction%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D9%2C%20color%3D%22%23333%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20mo.mpl.interactive(fig_scatter)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%202%20%C2%B7%20Correlation%20Analysis%0A%0A%20%20%20%20**Pearson%20r%20in%20plain%20English%3A**%20r%20measures%20the%20strength%20and%20direction%20of%20the%20*linear*%20association%0A%20%20%20%20between%20two%20variables.%20r%20%3D%20%2B1%20is%20a%20perfect%20upward%20line%3B%20r%20%3D%20%E2%88%921%20is%20a%20perfect%20downward%20line%3B%0A%20%20%20%20r%20%3D%200%20means%20no%20linear%20pattern%20%E2%80%94%20but%20nonlinear%20relationships%20can%20still%20exist.%0A%20%20%20%20r%20does%20not%20measure%20overall%20relatedness%2C%20only%20linear%20relatedness.%0A%0A%20%20%20%20For%20each%20predictor%E2%80%93response%20pair%2C%20we%20test%20the%20following%20hypotheses%20following%20the%0A%20%20%20%207-step%20hypothesis-testing%20procedure%3A%0A%0A%20%20%20%20%3E%20**H%E2%82%80%3A**%20%CF%81%20%3D%200%20(no%20linear%20relationship)%0A%20%20%20%20%3E%20**H%E2%82%81%3A**%20%CF%81%20%E2%89%A0%200%0A%20%20%20%20%3E%20**Test%20statistic%3A**%20T%E2%82%80%20%3D%20r%E2%88%9A%5B(n%E2%88%922)%20%2F%20(1%E2%88%92r%C2%B2)%5D%2C%20%20T%E2%82%80%20~%20t(n%E2%88%922)%0A%20%20%20%20%3E%20**%CE%B1%20%3D%200.05**%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20panel%2C%20pd%2C%20stats)%3A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Run%20all%208%20correlation%20tests%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20_predictors%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22Avg_Temp_C%22%2C%20%20%20%20%20%20%20%20%20%22Temperature%20(X%E2%82%81)%22%2C%20%20%20%20%20%22Avg_Temp_C%22)%2C%0A%20%20%20%20%20%20%20%20(%22Rain_mm%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%22Rainfall%20(X%E2%82%82)%22%2C%20%20%20%20%20%20%20%20%22Rain_mm%22)%2C%0A%20%20%20%20%20%20%20%20(%22ln_Population%22%2C%20%20%20%20%20%20%22ln(Population)%20(X%E2%82%83)%22%2C%20%20%22ln_Population%22)%2C%0A%20%20%20%20%20%20%20%20(%22Oil_Price_Brent_USD%22%2C%22Oil%20Price%20(X%E2%82%84)%22%2C%20%20%20%20%20%20%20%22Oil_Price_Brent_USD%22)%2C%0A%20%20%20%20%5D%0A%20%20%20%20_responses%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22ln_Production%22%2C%20%20%20%22ln(Production)%20(Y%E2%82%81)%22)%2C%0A%20%20%20%20%20%20%20%20(%22ln_Export_Value%22%2C%20%22ln(Export%20Value)%20(Y%E2%82%82)%22)%2C%0A%20%20%20%20%5D%0A%0A%20%20%20%20_corr_rows%20%3D%20%5B%5D%0A%20%20%20%20for%20_pred_col%2C%20_pred_label%2C%20_%20in%20_predictors%3A%0A%20%20%20%20%20%20%20%20for%20_resp_col%2C%20_resp_label%20in%20_responses%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_d%20%3D%20panel%5B%5B_pred_col%2C%20_resp_col%5D%5D.dropna()%0A%20%20%20%20%20%20%20%20%20%20%20%20_n%20%3D%20len(_d)%0A%20%20%20%20%20%20%20%20%20%20%20%20_r%2C%20_p%20%3D%20stats.pearsonr(_d%5B_pred_col%5D%2C%20_d%5B_resp_col%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20_t0%20%3D%20_r%20*%20np.sqrt((_n%20-%202)%20%2F%20(1%20-%20_r**2))%0A%20%20%20%20%20%20%20%20%20%20%20%20_reject%20%3D%20_p%20%3C%200.05%0A%20%20%20%20%20%20%20%20%20%20%20%20_rs%2C%20_ps%20%3D%20stats.spearmanr(_d%5B_pred_col%5D%2C%20_d%5B_resp_col%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20_reject_s%20%3D%20_ps%20%3C%200.05%0A%20%20%20%20%20%20%20%20%20%20%20%20_corr_rows.append(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Predictor%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20_pred_label%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Response%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20_resp_label%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22n%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_n%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22r%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_r%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22T%E2%82%80%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_t0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22df%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_n%20-%202%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22p-value%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_p%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Reject%20H%E2%82%80%3F%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%22Yes%20%E2%9C%93%22%20if%20_reject%20else%20%22No%20%E2%9C%97%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%CF%81_s%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_rs%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22p%20(Spearman)%22%3A%20%20%20%20%20%20%20%20%20%20_ps%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Reject%20H%E2%82%80%3F%20(Spearman)%22%3A%20%22Yes%20%E2%9C%93%22%20if%20_reject_s%20else%20%22No%20%E2%9C%97%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Conclusion%22%3A%20%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22Significant%20%7B'positive'%20if%20_r%20%3E%200%20else%20'negative'%7D%20linear%20relationship%20(%CE%B1%3D0.05)%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20_reject%20else%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Insufficient%20evidence%20to%20reject%20H%E2%82%80%20(%CE%B1%3D0.05)%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%0A%0A%20%20%20%20corr_df%20%3D%20pd.DataFrame(_corr_rows)%0A%20%20%20%20return%20(corr_df%2C)%0A%0A%0A%40app.cell%0Adef%20_(corr_df%2C%20mo)%3A%0A%20%20%20%20_display%20%3D%20corr_df.copy()%0A%20%20%20%20_display%5B%22r%22%5D%20%20%20%20%20%20%20%20%20%20%20%20%3D%20_display%5B%22r%22%5D.map(lambda%20x%3A%20f%22%7Bx%3A.4f%7D%22)%0A%20%20%20%20_display%5B%22T%E2%82%80%22%5D%20%20%20%20%20%20%20%20%20%20%20%3D%20_display%5B%22T%E2%82%80%22%5D.map(lambda%20x%3A%20f%22%7Bx%3A.3f%7D%22)%0A%20%20%20%20_display%5B%22p-value%22%5D%20%20%20%20%20%20%3D%20_display%5B%22p-value%22%5D.map(lambda%20x%3A%20f%22%7Bx%3A.4f%7D%22%20if%20x%20%3E%3D%200.0001%20else%20%22%3C%200.0001%22)%0A%20%20%20%20_display%5B%22%CF%81_s%22%5D%20%20%20%20%20%20%20%20%20%20%3D%20_display%5B%22%CF%81_s%22%5D.map(lambda%20x%3A%20f%22%7Bx%3A.4f%7D%22)%0A%20%20%20%20_display%5B%22p%20(Spearman)%22%5D%20%3D%20_display%5B%22p%20(Spearman)%22%5D.map(lambda%20x%3A%20f%22%7Bx%3A.4f%7D%22%20if%20x%20%3E%3D%200.0001%20else%20%22%3C%200.0001%22)%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%202.1%20Pearson%20Correlation%20Results%20(8%20tests)%0A%0A%20%20%20%20%20%20%20%20%7Bmo.as_html(_display%5B%5B%22Predictor%22%2C%22Response%22%2C%22n%22%2C%22r%22%2C%22T%E2%82%80%22%2C%22df%22%2C%22p-value%22%2C%22Reject%20H%E2%82%80%3F%22%2C%22Conclusion%22%5D%5D)%7D%0A%0A%20%20%20%20%20%20%20%20%23%23%23%202.1b%20Spearman%20Correlation%20%E2%80%94%20Rank-Based%20Cross-Check%0A%0A%20%20%20%20%20%20%20%20Spearman%20%CF%81%20is%20rank-based%20and%20less%20sensitive%20to%20the%20fat-tailed%20residuals%20visible%20in%20the%20%C2%A74%20Q-Q%20plots.%0A%20%20%20%20%20%20%20%20Consistent%20results%20across%20both%20tests%20strengthen%20each%20conclusion.%0A%0A%20%20%20%20%20%20%20%20%7Bmo.as_html(_display%5B%5B%22Predictor%22%2C%22Response%22%2C%22n%22%2C%22%CF%81_s%22%2C%22p%20(Spearman)%22%2C%22Reject%20H%E2%82%80%3F%20(Spearman)%22%5D%5D)%7D%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3E%20**%5BProcedure%3A%20Correlation%20t-test%5D**%20The%20T%E2%82%80%20and%20df%20columns%20connect%20directly%20to%20the%0A%20%20%20%20%3E%20t-distribution.%20Under%20H%E2%82%80%3A%20%CF%81%20%3D%200%2C%20the%20test%20statistic%20%24T_0%20%3D%20r%5Csqrt%7B(n-2)%2F(1-r%5E2)%7D%24%0A%20%20%20%20%3E%20follows%20a%20t-distribution%20with%20**df%20%3D%20n%20%E2%88%92%202**%20degrees%20of%20freedom%20(see%20*%5B%5Bdistributions%5D%5D*%0A%20%20%20%20%3E%20for%20the%20t%20critical%20value%20table).%20With%20n%20%E2%89%88%201%2C800%20here%2C%20df%20%E2%89%88%201%2C798%20and%20the%20critical%0A%20%20%20%20%3E%20value%20is%20%24t_%7B0.025%2C%5C%2C1798%7D%20%5Capprox%201.960%24.%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20**Step%205%20of%20the%207-step%20procedure**%20(*%5B%5Bhypothesis-testing-overview%5D%5D*)%3A%20Reject%20H%E2%82%80%20if%0A%20%20%20%20%3E%20%7CT%E2%82%80%7C%20%3E%201.96%20**or**%20equivalently%20if%20p-value%20%3C%20%CE%B1%20%3D%200.05%20%E2%80%94%20both%20criteria%20appear%20in%20the%0A%20%20%20%20%3E%20table%20above.%20Any%20row%20where%20both%20conditions%20agree%20is%20the%20strongest%20result.%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20**Spearman%20cross-check%20(%C2%A72.1b)%3A**%20Pearson%20r%20assumes%20a%20linear%20relationship%20and%20is%0A%20%20%20%20%3E%20sensitive%20to%20outliers.%20Spearman%20%CF%81%E2%82%9B%20is%20rank-based%20%E2%80%94%20it%20detects%20any%20monotone%20relationship%0A%20%20%20%20%3E%20and%20is%20less%20affected%20by%20the%20heavy%20tails%20visible%20in%20the%20Q-Q%20plots%20(%C2%A74).%20Consistent%0A%20%20%20%20%3E%20%22Yes%20%E2%9C%93%22%20across%20both%20tests%20is%20stronger%20evidence%20than%20either%20alone.%0A%20%20%20%20%3E%20See%20*%5B%5Bcorrelation-transformations%5D%5D*%20for%20both%20test%20formulas.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%23%20Teacher-phrasing%20template%20for%20correlation%20conclusions%0A%0A%20%20%20%20When%20writing%20conclusions%20about%20correlation%20tests%2C%20use%20this%20sentence%20pattern%3A%0A%0A%20%20%20%20%3E%20*%22p-value%20%3D%20X%20%3C%20%CE%B1%20%3D%200.05.%20We%20reject%20H%E2%82%80%3A%20%CF%81%20%3D%200.%20There%20is%20sufficient%20evidence%20of%20a%20significant%0A%20%20%20%20%3E%20%5Bpositive%2Fnegative%5D%20linear%20relationship%20between%20%5Bpredictor%5D%20and%20%5Bresponse%5D%20(r%20%3D%20X).%22*%0A%0A%20%20%20%20If%20the%20test%20fails%20to%20reject%3A%0A%0A%20%20%20%20%3E%20*%22p-value%20%3D%20X%20%3E%20%CE%B1%20%3D%200.05.%20We%20fail%20to%20reject%20H%E2%82%80%3A%20%CF%81%20%3D%200.%20There%20is%20insufficient%20evidence%20to%0A%20%20%20%20%3E%20conclude%20that%20a%20linear%20relationship%20exists%20between%20%5Bpredictor%5D%20and%20%5Bresponse%5D.%22*%0A%0A%20%20%20%20Use%20%22fail%20to%20reject%22%20%E2%80%94%20never%20%22accept%20H%E2%82%80%22%20or%20%22prove%20no%20relationship%20exists.%22%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%23%20Correlation%20matrix%20as%20a%20map%0A%0A%20%20%20%20The%20heatmap%20below%20shows%20every%20pairwise%20Pearson%20r%20in%20the%20dataset%20at%20a%20glance.%20It%20is%20useful%20for%0A%20%20%20%20spotting%20broad%20patterns%20%E2%80%94%20for%20example%2C%20whether%20predictors%20are%20strongly%20correlated%20with%20each%20other%0A%20%20%20%20(multicollinearity)%20or%20with%20the%20responses.%0A%0A%20%20%20%20**What%20the%20heatmap%20cannot%20tell%20you%3A**%20how%20much%20each%20predictor%20contributes%20while%20the%20others%20are%0A%20%20%20%20held%20fixed.%20That%20question%20requires%20regression%20(%C2%A73).%20Use%20the%20heatmap%20as%20orientation%2C%20not%20conclusion.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%202.2%20Correlation%20Heatmap%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20panel%2C%20plt%2C%20sns)%3A%0A%20%20%20%20_cols%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22Avg_Temp_C%22%3A%20%20%20%20%20%20%20%20%20%20%22Temp%20(X%E2%82%81)%22%2C%0A%20%20%20%20%20%20%20%20%22Rain_mm%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%22Rainfall%20(X%E2%82%82)%22%2C%0A%20%20%20%20%20%20%20%20%22ln_Population%22%3A%20%20%20%20%20%20%20%22ln(Pop)%20(X%E2%82%83)%22%2C%0A%20%20%20%20%20%20%20%20%22Oil_Price_Brent_USD%22%3A%20%22Oil%20Price%20(X%E2%82%84)%22%2C%0A%20%20%20%20%20%20%20%20%22ln_Production%22%3A%20%20%20%20%20%20%20%22ln(Prod)%20(Y%E2%82%81)%22%2C%0A%20%20%20%20%20%20%20%20%22ln_Export_Value%22%3A%20%20%20%20%20%22ln(Export)%20(Y%E2%82%82)%22%2C%0A%20%20%20%20%7D%0A%20%20%20%20_data%20%3D%20panel%5Blist(_cols.keys())%5D.rename(columns%3D_cols).dropna()%0A%20%20%20%20_corr_mat%20%3D%20_data.corr()%0A%0A%20%20%20%20fig_heat%2C%20ax_heat%20%3D%20plt.subplots(figsize%3D(8%2C%206))%0A%20%20%20%20sns.heatmap(%0A%20%20%20%20%20%20%20%20_corr_mat%2C%20annot%3DTrue%2C%20fmt%3D%22.3f%22%2C%20cmap%3D%22RdBu_r%22%2C%0A%20%20%20%20%20%20%20%20center%3D0%2C%20vmin%3D-1%2C%20vmax%3D1%2C%0A%20%20%20%20%20%20%20%20linewidths%3D0.5%2C%20ax%3Dax_heat%2C%0A%20%20%20%20%20%20%20%20annot_kws%3D%7B%22size%22%3A%2010%7D%0A%20%20%20%20)%0A%20%20%20%20ax_heat.set_title(%22Pearson%20Correlation%20Matrix%20%E2%80%94%20Predictors%20and%20Responses%22%2C%20pad%3D12)%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20mo.mpl.interactive(fig_heat)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%203%20%C2%B7%20Multiple%20Linear%20Regression%0A%0A%20%20%20%20Two%20models%20are%20fit%20with%20five%20predictor%20terms.%20Rainfall%20is%20split%20into%20two%20components%3A%0A%20%20%20%20%24%5Coverline%7B%5Ctext%7BRain%7D%7D_%7B%5Ctext%7Bcountry%7D%7D%24%20%3D%20each%20country's%20long-run%20mean%20(structural%20climate)%3B%0A%20%20%20%20%24%5Ctext%7BRain%7D_%7B%5Ctext%7Bwithin%7D%7D%24%20%3D%20each%20year's%20deviation%20from%20that%20mean%20(interannual%20variation).%0A%0A%20%20%20%20**Model%20A%20%E2%80%94%20Production%3A**%0A%20%20%20%20%24%24%5Cln(%5Ctext%7BProduction%7D)%20%3D%20%5Cbeta_0%20%2B%20%5Cbeta_1%5C%2C%5Ctext%7BTemp%7D%20%2B%20%5Cbeta_%7B2a%7D%5C%2C%5Coverline%7B%5Ctext%7BRain%7D%7D_%7B%5Ctext%7Bcountry%7D%7D%20%2B%20%5Cbeta_%7B2b%7D%5C%2C%5Ctext%7BRain%7D_%7B%5Ctext%7Bwithin%7D%7D%20%2B%20%5Cbeta_3%5C%2C%5Cln(%5Ctext%7BPopulation%7D)%20%2B%20%5Cbeta_4%5C%2C%5Ctext%7BOil%7D%20%2B%20%5Cvarepsilon%24%24%0A%0A%20%20%20%20**Model%20B%20%E2%80%94%20Export%20Revenue%3A**%0A%20%20%20%20%24%24%5Cln(%5Ctext%7BExport%5C_Value%7D)%20%3D%20%5Cbeta_0%20%2B%20%5Cbeta_1%5C%2C%5Ctext%7BTemp%7D%20%2B%20%5Cbeta_%7B2a%7D%5C%2C%5Coverline%7B%5Ctext%7BRain%7D%7D_%7B%5Ctext%7Bcountry%7D%7D%20%2B%20%5Cbeta_%7B2b%7D%5C%2C%5Ctext%7BRain%7D_%7B%5Ctext%7Bwithin%7D%7D%20%2B%20%5Cbeta_3%5C%2C%5Cln(%5Ctext%7BPopulation%7D)%20%2B%20%5Cbeta_4%5C%2C%5Ctext%7BOil%7D%20%2B%20%5Cvarepsilon%24%24%0A%0A%20%20%20%20**Overall%20F-test%20H%E2%82%80%3A**%20%CE%B2%E2%82%81%20%3D%20%CE%B2%E2%82%82%E2%82%90%20%3D%20%CE%B2%E2%82%82%E1%B5%A6%20%3D%20%CE%B2%E2%82%83%20%3D%20%CE%B2%E2%82%84%20%3D%200%20(model%20has%20no%20explanatory%20power)%0A%20%20%20%20**Individual%20t-tests%20H%E2%82%80%3A**%20%CE%B2%E2%B1%BC%20%3D%200%20for%20each%20predictor%20term%0A%20%20%20%20**%CE%B1%20%3D%200.05**%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%23%20What%20MLR%20adds%20beyond%20correlation%0A%0A%20%20%20%20Correlation%20(%C2%A72)%20measures%20pairwise%20association%20between%20one%20predictor%20and%20one%20response.%0A%20%20%20%20Multiple%20linear%20regression%20fits%20all%20four%20predictors%20simultaneously%2C%20so%20each%20coefficient%20is%0A%20%20%20%20interpreted%20as%20*holding%20all%20other%20predictors%20constant*.%20For%20example%3A%20the%20temperature%20coefficient%0A%20%20%20%20%CE%B2%E2%82%81%20estimates%20the%20association%20between%20temperature%20and%20production%20**after%20accounting%20for%20differences%0A%20%20%20%20in%20population%2C%20rainfall%2C%20and%20oil%20price**.%20This%20is%20what%20separates%20regression%20from%20a%20collection%0A%20%20%20%20of%20bivariate%20correlations.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%23%20Why%20rainfall%20is%20split%20into%20two%20terms%0A%0A%20%20%20%20Raw%20%60Rain_mm%60%20confounds%20two%20different%20questions.%20The%20decomposition%20separates%20them%3A%0A%0A%20%20%20%20-%20**Rain_mm_country_mean%20(%CE%B2%E2%82%82%E2%82%90)%3A**%20Each%20country's%20long-run%20average%20rainfall.%20Answers%3A%20*Do%20wetter%0A%20%20%20%20%20%20climates%20structurally%20produce%20more%20coffee%3F*%20This%20is%20a%20cross-country%20comparison.%0A%20%20%20%20-%20**Rain_mm_within%20(%CE%B2%E2%82%82%E1%B5%A6)%3A**%20Each%20year's%20deviation%20from%20that%20country's%20mean.%20Answers%3A%20*Does%20an%0A%20%20%20%20%20%20unusually%20wet%20year%20boost%20production%3F*%20This%20is%20within-country%20variation%20over%20time.%0A%0A%20%20%20%20The%20two%20coefficients%20answer%20different%20questions%20and%20should%20not%20be%20interpreted%20interchangeably.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%23%20Reading%20the%20regression%20output%0A%0A%20%20%20%20**R%C2%B2%20and%20adjusted%20R%C2%B2**%20both%20measure%20variation%20explained.%20Adjusted%20R%C2%B2%20penalizes%20adding%20predictors%0A%20%20%20%20and%20is%20reported%20here%20because%20it%20allows%20fair%20comparison%20across%20models.%0A%20%20%20%20Teacher%20phrasing%3A%20*%22X%25%20of%20the%20variation%20in%20%5Bresponse%5D%20is%20explained%20by%20the%20regression%20model.%22*%0A%0A%20%20%20%20**Coefficient%20table%20column%20guide%3A**%0A%0A%20%20%20%20%7C%20Column%20%7C%20Meaning%20%7C%0A%20%20%20%20%7C---%7C---%7C%0A%20%20%20%20%7C%20%CE%B2%CC%82%20(coef)%20%7C%20Estimated%20change%20in%20ln(Y)%20per%20one-unit%20increase%20in%20X%2C%20holding%20all%20other%20predictors%20constant%20%7C%0A%20%20%20%20%7C%20Robust%20SE%20%7C%20Standard%20error%20of%20%CE%B2%CC%82%20under%20HC3%20correction%20%E2%80%94%20measures%20estimation%20uncertainty%20%7C%0A%20%20%20%20%7C%20Robust%20t%E2%82%80%20%7C%20t-statistic%20%3D%20%CE%B2%CC%82%20%2F%20Robust%20SE%20%E2%80%94%20how%20many%20SEs%20the%20estimate%20is%20from%20zero%20%7C%0A%20%20%20%20%7C%20p-value%20%7C%20Probability%20of%20observing%20this%20t%E2%82%80%20if%20H%E2%82%80%3A%20%CE%B2%E2%B1%BC%20%3D%200%20were%20true%20%E2%80%94%20compare%20to%20%CE%B1%20%3D%200.05%20%7C%0A%20%20%20%20%7C%20Robust%2095%25%20CI%20%7C%20Plausible%20range%20for%20the%20true%20coefficient%20%7C%0A%20%20%20%20%7C%20Sig%3F%20%7C%20%22Yes%20%E2%9C%93%22%20if%20p-value%20%3C%200.05%20%7C%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20panel%2C%20pd%2C%20smf)%3A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Fit%20both%20models%20(HC3%20robust%20standard%20errors)%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20FORMULA_A%20%3D%20(%0A%20%20%20%20%20%20%20%20%22ln_Production%20%20~%20Avg_Temp_C%20%2B%20Rain_mm_country_mean%20%2B%20Rain_mm_within%22%0A%20%20%20%20%20%20%20%20%22%20%2B%20ln_Population%20%2B%20Oil_Price_Brent_USD%22%0A%20%20%20%20)%0A%20%20%20%20FORMULA_B%20%3D%20(%0A%20%20%20%20%20%20%20%20%22ln_Export_Value%20~%20Avg_Temp_C%20%2B%20Rain_mm_country_mean%20%2B%20Rain_mm_within%22%0A%20%20%20%20%20%20%20%20%22%20%2B%20ln_Population%20%2B%20Oil_Price_Brent_USD%22%0A%20%20%20%20)%0A%0A%20%20%20%20panel_model%20%3D%20panel.dropna(subset%3D%5B%0A%20%20%20%20%20%20%20%20%22ln_Production%22%2C%20%22ln_Export_Value%22%2C%0A%20%20%20%20%20%20%20%20%22Avg_Temp_C%22%2C%20%22Rain_mm_country_mean%22%2C%20%22Rain_mm_within%22%2C%0A%20%20%20%20%20%20%20%20%22ln_Population%22%2C%20%22Oil_Price_Brent_USD%22%0A%20%20%20%20%5D)%0A%0A%20%20%20%20%23%20Raw%20OLS%20(retained%20for%20influence%20diagnostics%20%E2%80%94%20OLSInfluence%20requires%20plain%20OLS)%0A%20%20%20%20ols_a%20%3D%20smf.ols(FORMULA_A%2C%20data%3Dpanel_model).fit()%0A%20%20%20%20ols_b%20%3D%20smf.ols(FORMULA_B%2C%20data%3Dpanel_model).fit()%0A%0A%20%20%20%20%23%20HC3%20heteroskedasticity-consistent%20fits%20%E2%80%94%20primary%20inference%0A%20%20%20%20model_a%20%3D%20smf.ols(FORMULA_A%2C%20data%3Dpanel_model).fit(cov_type%3D%22HC3%22)%0A%20%20%20%20model_b%20%3D%20smf.ols(FORMULA_B%2C%20data%3Dpanel_model).fit(cov_type%3D%22HC3%22)%0A%0A%20%20%20%20def%20_model_summary_table(result%2C%20model_name)%3A%0A%20%20%20%20%20%20%20%20coef_df%20%3D%20pd.DataFrame(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Term%22%3A%20%20%20%20%20%20%20%20%20%20%20%20%20result.params.index%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%CE%B2%CC%82%20(coef)%22%3A%20%20%20%20%20%20%20%20result.params.values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Robust%20SE%22%3A%20%20%20%20%20%20%20%20result.bse.values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Robust%20t%E2%82%80%22%3A%20%20%20%20%20%20%20result.tvalues.values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22p-value%22%3A%20%20%20%20%20%20%20%20%20%20result.pvalues.values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Robust%2095%25%20CI%20Lo%22%3A%20result.conf_int()%5B0%5D.values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Robust%2095%25%20CI%20Hi%22%3A%20result.conf_int()%5B1%5D.values%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20coef_df%5B%22Sig%3F%22%5D%20%3D%20coef_df%5B%22p-value%22%5D.apply(lambda%20p%3A%20%22Yes%20%E2%9C%93%22%20if%20p%20%3C%200.05%20else%20%22No%20%E2%9C%97%22)%0A%20%20%20%20%20%20%20%20for%20c%20in%20%5B%22%CE%B2%CC%82%20(coef)%22%2C%20%22Robust%20SE%22%2C%20%22Robust%20t%E2%82%80%22%2C%20%22Robust%2095%25%20CI%20Lo%22%2C%20%22Robust%2095%25%20CI%20Hi%22%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20coef_df%5Bc%5D%20%3D%20coef_df%5Bc%5D.map(lambda%20x%3A%20f%22%7Bx%3A.4f%7D%22)%0A%20%20%20%20%20%20%20%20coef_df%5B%22p-value%22%5D%20%3D%20coef_df%5B%22p-value%22%5D.map(lambda%20x%3A%20f%22%7Bx%3A.4f%7D%22%20if%20x%20%3E%3D%200.0001%20else%20%22%3C%200.0001%22)%0A%20%20%20%20%20%20%20%20return%20coef_df%0A%0A%20%20%20%20coef_a%20%3D%20_model_summary_table(model_a%2C%20%22Model%20A%22)%0A%20%20%20%20coef_b%20%3D%20_model_summary_table(model_b%2C%20%22Model%20B%22)%0A%0A%20%20%20%20%23%20F-test%20summary%20(R%C2%B2%20and%20F%20come%20from%20base%20OLS%3B%20HC3%20affects%20SE%2Ft%2Fp%20only)%0A%20%20%20%20_f_rows%20%3D%20%5B%5D%0A%20%20%20%20for%20_name%2C%20_res%20in%20%5B(%22Model%20A%20%E2%80%94%20ln(Production)%22%2C%20model_a)%2C%20(%22Model%20B%20%E2%80%94%20ln(Export%20Revenue)%22%2C%20model_b)%5D%3A%0A%20%20%20%20%20%20%20%20_f_rows.append(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Model%22%3A%20%20%20%20%20%20_name%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22n%22%3A%20%20%20%20%20%20%20%20%20%20int(_res.nobs)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22R%C2%B2%22%3A%20%20%20%20%20%20%20%20%20f%22%7B_res.rsquared%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22R%C2%B2_adj%22%3A%20%20%20%20%20f%22%7B_res.rsquared_adj%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22F%E2%82%80%22%3A%20%20%20%20%20%20%20%20%20f%22%7B_res.fvalue%3A.3f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22df%20(reg)%22%3A%20%20%20int(_res.df_model)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22df%20(error)%22%3A%20int(_res.df_resid)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22p(F)%22%3A%20%20%20%20%20%20%20%22%3C%200.0001%22%20if%20_res.f_pvalue%20%3C%200.0001%20else%20f%22%7B_res.f_pvalue%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Reject%20H%E2%82%80%3F%22%3A%20%22Yes%20%E2%9C%93%22%20if%20_res.f_pvalue%20%3C%200.05%20else%20%22No%20%E2%9C%97%22%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20f_df%20%3D%20pd.DataFrame(_f_rows)%0A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%203.1%20Overall%20Model%20Significance%20(F-test)%0A%0A%20%20%20%20%20%20%20%20%7Bmo.as_html(f_df)%7D%0A%0A%20%20%20%20%20%20%20%20---%0A%0A%20%20%20%20%20%20%20%20%23%23%23%203.2%20Model%20A%20%E2%80%94%20Coefficients%3A%20ln(Production)%0A%20%20%20%20%20%20%20%20*Standard%20errors%20and%20CIs%20are%20HC3%20heteroskedasticity-consistent.*%0A%0A%20%20%20%20%20%20%20%20%7Bmo.as_html(coef_a)%7D%0A%0A%20%20%20%20%20%20%20%20---%0A%0A%20%20%20%20%20%20%20%20%23%23%23%203.3%20Model%20B%20%E2%80%94%20Coefficients%3A%20ln(Export%20Revenue)%0A%20%20%20%20%20%20%20%20*Standard%20errors%20and%20CIs%20are%20HC3%20heteroskedasticity-consistent.*%0A%0A%20%20%20%20%20%20%20%20%7Bmo.as_html(coef_b)%7D%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%20model_a%2C%20model_b%2C%20ols_a%2C%20ols_b%2C%20panel_model%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3E%20**%5BConstruct%3A%20SS%20Decomposition%20%26%20F-test%5D**%20The%20F-test%20row%20above%20is%20the%20*overall%20model%20significance%20test*%0A%20%20%20%20%3E%20from%20*%5B%5Bregression-ht%5D%5D*.%20Its%20structure%20comes%20from%20the%20sum-of-squares%20identity%0A%20%20%20%20%3E%20(*%5B%5Bss-decomposition%5D%5D*)%3A%20%24SS_T%20%3D%20SS_R%20%2B%20SS_E%24%2C%20where%20%24SS_R%24%20is%20the%20variation%20*explained*%20by%0A%20%20%20%20%3E%20the%20model%20and%20%24SS_E%24%20is%20the%20unexplained%20residual%20variation.%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20**Reading%20the%20df%20columns%3A**%20%60df%20(reg)%60%20%3D%20k%20%3D%20number%20of%20predictors%20(here%20k%20%3D%205%20including%20both%0A%20%20%20%20%3E%20rainfall%20terms).%20%60df%20(error)%60%20%3D%20n%20%E2%88%92%20k%20%E2%88%92%201%20%E2%89%88%201%2C800%20%E2%88%92%205%20%E2%88%92%201%20%3D%201%2C794.%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20**F%E2%82%80%20formula%3A**%20%24F_0%20%3D%20%5Cfrac%7BMS_R%7D%7BMS_E%7D%20%3D%20%5Cfrac%7BSS_R%20%2F%20k%7D%7BSS_E%20%2F%20(n-k-1)%7D%24.%20Reject%20H%E2%82%80%20(all%0A%20%20%20%20%3E%20%CE%B2%E2%B1%BC%20%3D%200)%20if%20F%E2%82%80%20%3E%20F%20critical%20%E2%89%88%202.22%20at%20%CE%B1%20%3D%200.05%20with%20df(5%2C%201794)%2C%20**or**%20if%20p(F)%20%3C%200.05.%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20**R%C2%B2%20and%20R%C2%B2_adj%3A**%20%24R%5E2%20%3D%20SS_R%20%2F%20SS_T%24%20%E2%80%94%20the%20fraction%20of%20total%20variance%20explained%20by%20the%20model.%0A%20%20%20%20%3E%20%24R%5E2_%7Badj%7D%24%20penalizes%20for%20the%20number%20of%20predictors%20k%3B%20use%20it%20to%20compare%20models%20with%20different%0A%20%20%20%20%3E%20numbers%20of%20terms.%20Individual%20coefficient%20t-tests%20(%24t_0%20%3D%20%5Chat%7B%5Cbeta%7D_j%20%2F%20SE_j%24%2C%20df%20%3D%20n%E2%88%92k%E2%88%921)%0A%20%20%20%20%3E%20test%20whether%20*each*%20predictor%20contributes%20after%20controlling%20for%20all%20others%20%E2%80%94%20see%20%C2%A73.2%2F3.3%20tables.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%23%20Confidence%20interval%20intuition%0A%0A%20%20%20%20Each%20bar%20in%20the%20coefficient%20plot%20shows%20the%20estimated%20effect%20of%20one%20predictor%20with%20a%2095%25%0A%20%20%20%20confidence%20interval.%20A%2095%25%20CI%20gives%20a%20plausible%20range%20for%20the%20true%20coefficient%3A%20if%20we%20repeated%0A%20%20%20%20this%20study%20many%20times%20with%20new%20samples%2C%20about%2095%25%20of%20those%20intervals%20would%20contain%20the%20true%20%CE%B2%E2%B1%BC.%0A%0A%20%20%20%20**Key%20link%20to%20significance%3A**%20A%20CI%20that%20crosses%20zero%20means%20zero%20is%20a%20plausible%20value%20for%20the%0A%20%20%20%20coefficient%20%E2%80%94%20consistent%20with%20failing%20to%20reject%20H%E2%82%80%3A%20%CE%B2%E2%B1%BC%20%3D%200%20at%20%CE%B1%20%3D%200.05.%0A%20%20%20%20Bars%20shown%20in%20**gray**%20cross%20zero%20and%20are%20not%20significant%3B%20**colored**%20bars%20do%20not%20cross%20zero%0A%20%20%20%20and%20are%20significant.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%203.4%20Coefficient%20Plot%20%E2%80%94%20Effect%20Sizes%20and%2095%25%20CIs%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ACCENT%2C%20ACCENT2%2C%20mo%2C%20model_a%2C%20model_b%2C%20np%2C%20plt)%3A%0A%20%20%20%20def%20_()%3A%0A%20%20%20%20%20%20%20%20_terms%20%3D%20%5B%22Avg_Temp_C%22%2C%20%22Rain_mm_country_mean%22%2C%20%22Rain_mm_within%22%2C%20%22ln_Population%22%2C%20%22Oil_Price_Brent_USD%22%5D%0A%20%20%20%20%20%20%20%20_labels%20%3D%20%5B%22Temp%20(X%E2%82%81)%22%2C%20%22Rainfall-between%20(X%E2%82%82%E2%82%90)%22%2C%20%22Rainfall-within%20(X%E2%82%82%E1%B5%A6)%22%2C%20%22ln(Pop)%20(X%E2%82%83)%22%2C%20%22Oil%20Price%20(X%E2%82%84)%22%5D%0A%0A%20%20%20%20%20%20%20%20fig_coef%2C%20axes_coef%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(13%2C%204)%2C%20sharey%3DTrue)%0A%20%20%20%20%20%20%20%20fig_coef.suptitle(%22Regression%20Coefficients%20with%2095%25%20Confidence%20Intervals%22%2C%20fontsize%3D13%2C%20fontweight%3D%22bold%22)%0A%0A%20%20%20%20%20%20%20%20for%20ax%2C%20result%2C%20title%2C%20color%20in%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(axes_coef%5B0%5D%2C%20model_a%2C%20%22Model%20A%20%E2%80%94%20ln(Production)%22%2C%20ACCENT)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(axes_coef%5B1%5D%2C%20model_b%2C%20%22Model%20B%20%E2%80%94%20ln(Export%20Revenue)%22%2C%20ACCENT2)%2C%0A%20%20%20%20%20%20%20%20%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_coefs%20%20%3D%20%5Bresult.params%5Bt%5D%20%20%20%20%20%20%20%20%20for%20t%20in%20_terms%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_lo%20%20%20%20%20%3D%20%5Bresult.conf_int().loc%5Bt%2C%200%5D%20for%20t%20in%20_terms%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_hi%20%20%20%20%20%3D%20%5Bresult.conf_int().loc%5Bt%2C%201%5D%20for%20t%20in%20_terms%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_errs%20%20%20%3D%20%5B%5Bc%20-%20lo%20for%20c%2C%20lo%20in%20zip(_coefs%2C%20_lo)%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Bhi%20-%20c%20for%20c%2C%20hi%20in%20zip(_coefs%2C%20_hi)%5D%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_pvals%20%20%3D%20%5Bresult.pvalues%5Bt%5D%20for%20t%20in%20_terms%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20_y%20%3D%20np.arange(len(_terms))%0A%20%20%20%20%20%20%20%20%20%20%20%20_colors%20%3D%20%5Bcolor%20if%20p%20%3C%200.05%20else%20%22%23BDBDBD%22%20for%20p%20in%20_pvals%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.axvline(0%2C%20color%3D%22%23888%22%2C%20linewidth%3D1%2C%20linestyle%3D%22--%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.barh(_y%2C%20_coefs%2C%20xerr%3D_errs%2C%20color%3D_colors%2C%20alpha%3D0.85%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height%3D0.5%2C%20error_kw%3Ddict(ecolor%3D%22%23333%22%2C%20capsize%3D4%2C%20linewidth%3D1.3))%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_yticks(_y)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_yticklabels(_labels)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(%22Coefficient%20value%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(title)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.annotate(%22Grey%20%3D%20not%20significant%20(%CE%B1%3D0.05)%22%2C%20xy%3D(0.98%2C%200.02)%2C%20xycoords%3D%22axes%20fraction%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ha%3D%22right%22%2C%20fontsize%3D8%2C%20color%3D%22%23888%22)%0A%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%20%20%20%20%20%20%20%20return%20mo.mpl.interactive(fig_coef)%0A%0A%0A%20%20%20%20_()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%204%20%C2%B7%20Model%20Adequacy%20Checks%0A%0A%20%20%20%20A%20**residual**%20is%20the%20actual%20observed%20value%20minus%20the%20model's%20predicted%20value%3A%20e%E1%B5%A2%20%3D%20y%E1%B5%A2%20%E2%88%92%20%C5%B7%E1%B5%A2.%20Residual%20plots%20reveal%20whether%20the%20model's%20assumptions%20hold%20in%20practice.%0A%0A%20%20%20%20%3E%20A%20visible%20pattern%20in%20residual%20plots%20is%20more%20concerning%20than%20a%20high%20R%C2%B2%20%E2%80%94%20R%C2%B2%20can%20look%20good%20even%20when%20regression%20assumptions%20are%20violated.%0A%0A%20%20%20%20For%20both%20models%2C%20we%20verify%20the%20four%20OLS%20regression%20assumptions%3A%0A%0A%20%20%20%201.%20**Linearity**%20%E2%80%94%20Residuals%20vs.%20Fitted%3A%20no%20systematic%20curve%0A%20%20%20%202.%20**Heteroskedasticity**%20%E2%80%94%20mitigated%20by%20HC3%20robust%20SEs%3B%20within-country%20serial%20correlation%20addressed%20in%20robustness%20section%20(%C2%A74.2)%0A%20%20%20%203.%20**Homoscedasticity**%20%E2%80%94%20Scale-location%20plot%3B%20residual%20spread%20vs.%20fitted%0A%20%20%20%204.%20**Normality%20of%20residuals**%20%E2%80%94%20Normal%20Q-Q%20plot%3B%20Shapiro-Wilk%20test%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ACCENT%2C%20ACCENT2%2C%20mo%2C%20model_a%2C%20model_b%2C%20np%2C%20plt%2C%20stats)%3A%0A%20%20%20%20def%20_()%3A%0A%20%20%20%20%20%20%20%20fig_diag%2C%20axes_diag%20%3D%20plt.subplots(2%2C%204%2C%20figsize%3D(17%2C%208))%0A%20%20%20%20%20%20%20%20fig_diag.suptitle(%22Model%20Adequacy%20Diagnostics%22%2C%20fontsize%3D13%2C%20fontweight%3D%22bold%22)%0A%0A%20%20%20%20%20%20%20%20for%20row_idx%2C%20(result%2C%20title%2C%20color)%20in%20enumerate(%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(model_a%2C%20%22Model%20A%20%E2%80%94%20ln(Production)%22%2C%20%20%20%20ACCENT)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(model_b%2C%20%22Model%20B%20%E2%80%94%20ln(Export%20Revenue)%22%2C%20ACCENT2)%2C%0A%20%20%20%20%20%20%20%20%5D)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20residuals%20%3D%20result.resid%0A%20%20%20%20%20%20%20%20%20%20%20%20fitted%20%20%20%20%3D%20result.fittedvalues%0A%20%20%20%20%20%20%20%20%20%20%20%20std_resid%20%3D%20residuals%20%2F%20residuals.std()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E2%94%80%E2%94%80%20Plot%201%3A%20Residuals%20vs%20Fitted%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20%20%20%20%20%20%20%20%20ax%20%3D%20axes_diag%5Brow_idx%2C%200%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.scatter(fitted%2C%20residuals%2C%20alpha%3D0.25%2C%20s%3D10%2C%20color%3Dcolor%2C%20linewidths%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.axhline(0%2C%20color%3D%22%23333%22%2C%20linewidth%3D1.2%2C%20linestyle%3D%22--%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(%22Fitted%20values%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel(%22Residuals%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(f%22%7Btitle%7D%5CnResiduals%20vs.%20Fitted%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E2%94%80%E2%94%80%20Plot%202%3A%20Normal%20Q-Q%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20%20%20%20%20%20%20%20%20ax%20%3D%20axes_diag%5Brow_idx%2C%201%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_osm%2C%20_osr%20%3D%20stats.probplot(residuals%2C%20dist%3D%22norm%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.scatter(_osm%5B0%5D%2C%20_osm%5B1%5D%2C%20alpha%3D0.3%2C%20s%3D10%2C%20color%3Dcolor%2C%20linewidths%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20_fit_line%20%3D%20np.polyfit(_osm%5B0%5D%2C%20_osm%5B1%5D%2C%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20_x_ql%20%3D%20np.linspace(min(_osm%5B0%5D)%2C%20max(_osm%5B0%5D)%2C%20200)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.plot(_x_ql%2C%20np.polyval(_fit_line%2C%20_x_ql)%2C%20color%3D%22%23333%22%2C%20linewidth%3D1.5%2C%20linestyle%3D%22--%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(%22Theoretical%20quantiles%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel(%22Sample%20quantiles%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(f%22%7Btitle%7D%5CnNormal%20Q-Q%20Plot%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E2%94%80%E2%94%80%20Plot%203%3A%20Scale-Location%20(%E2%88%9A%7Cstd%20resid%7C%20vs%20fitted)%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20%20%20%20%20%20%20%20%20ax%20%3D%20axes_diag%5Brow_idx%2C%202%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.scatter(fitted%2C%20np.sqrt(np.abs(std_resid))%2C%20alpha%3D0.25%2C%20s%3D10%2C%20color%3Dcolor%2C%20linewidths%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.axhline(1%2C%20color%3D%22%23333%22%2C%20linewidth%3D1%2C%20linestyle%3D%22--%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(%22Fitted%20values%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel(%22%E2%88%9A%7CStandardized%20residuals%7C%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(f%22%7Btitle%7D%5CnScale-Location%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E2%94%80%E2%94%80%20Plot%204%3A%20Residual%20histogram%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20%20%20%20%20%20%20%20%20ax%20%3D%20axes_diag%5Brow_idx%2C%203%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.hist(residuals%2C%20bins%3D35%2C%20color%3Dcolor%2C%20alpha%3D0.8%2C%20edgecolor%3D%22white%22%2C%20linewidth%3D0.4)%0A%20%20%20%20%20%20%20%20%20%20%20%20_sw_stat%2C%20_sw_p%20%3D%20stats.shapiro(residuals)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(f%22%7Btitle%7D%5CnResidual%20Distribution%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(%22Residual%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel(%22Frequency%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.annotate(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22Shapiro-Wilk%5CnW%20%3D%20%7B_sw_stat%3A.4f%7D%5Cnp%20%3D%20%7B'%3C%200.0001'%20if%20_sw_p%20%3C%200.0001%20else%20f'%7B_sw_p%3A.4f%7D'%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20xy%3D(0.97%2C%200.93)%2C%20xycoords%3D%22axes%20fraction%22%2C%20ha%3D%22right%22%2C%20va%3D%22top%22%2C%20fontsize%3D8%2C%20color%3D%22%23333%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bbox%3Ddict(boxstyle%3D%22round%2Cpad%3D0.3%22%2C%20facecolor%3D%22white%22%2C%20alpha%3D0.7)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%20%20%20%20%20%20%20%20return%20mo.mpl.interactive(fig_diag)%0A%0A%0A%20%20%20%20_()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3E%20**%5BProcedure%3A%20Model%20Adequacy%20Checks%5D**%20Each%20of%20the%20four%20plots%20above%20tests%20one%20of%20the%20four%20OLS%0A%20%20%20%20%3E%20regression%20assumptions%20from%20*%5B%5Bmodel-adequacy%5D%5D*%3A%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20%7C%20Plot%20%7C%20Assumption%20tested%20%7C%20What%20to%20look%20for%20%7C%0A%20%20%20%20%3E%20%7C------%7C-------------------%7C-----------------%7C%0A%20%20%20%20%3E%20%7C%20Residuals%20vs.%20Fitted%20%7C%20**Linearity**%20%E2%80%94%20mean%20of%20residuals%20%3D%200%20at%20all%20fitted%20values%20%7C%20No%20curve%3B%20random%20scatter%20around%20the%20horizontal%20dashed%20line%20%7C%0A%20%20%20%20%3E%20%7C%20Normal%20Q-Q%20%7C%20**Normality**%20%E2%80%94%20residuals%20~%20N(0%2C%20%CF%83%C2%B2)%20%7C%20Points%20follow%20the%20diagonal%20reference%20line%3B%20heavy%20tails%20%3D%20departure%20%7C%0A%20%20%20%20%3E%20%7C%20Scale-Location%20%7C%20**Homoscedasticity**%20%E2%80%94%20constant%20residual%20variance%20%7C%20Horizontal%20band%3B%20a%20fan%20shape%20indicates%20heteroskedasticity%20%7C%0A%20%20%20%20%3E%20%7C%20Residual%20histogram%20%7C%20**Normality**%20(complementary%20view)%20%7C%20Approximately%20bell-shaped%3B%20Shapiro-Wilk%20W%20quantifies%20the%20test%20%7C%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20**Which%20matters%20most%20here%3F**%20With%20n%20%E2%89%88%201%2C800%2C%20the%20Central%20Limit%20Theorem%20makes%20the%20normality%0A%20%20%20%20%3E%20assumption%20least%20critical%20%E2%80%94%20inference%20is%20robust%20to%20modest%20departures.%20Heteroskedasticity%0A%20%20%20%20%3E%20(fan%20shape%20in%20Scale-Location)%20is%20more%20consequential%20because%20it%20inflates%20OLS%20standard%20errors%0A%20%20%20%20%3E%20unevenly%20%E2%80%94%20which%20is%20why%20HC3%20robust%20SEs%20are%20used%20for%20all%20inference%20(%C2%A73.2%2F3.3).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20model_a%2C%20model_b%2C%20stats)%3A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Shapiro-Wilk%20formal%20results%20table%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%20%20%20%20_results%20%3D%20%5B%5D%0A%20%20%20%20for%20_name%2C%20_res%20in%20%5B(%22Model%20A%20%E2%80%94%20ln(Production)%22%2C%20model_a)%2C%20(%22Model%20B%20%E2%80%94%20ln(Export%20Revenue)%22%2C%20model_b)%5D%3A%0A%20%20%20%20%20%20%20%20_resid%20%3D%20_res.resid.values%0A%20%20%20%20%20%20%20%20_w%2C%20_p%20%3D%20stats.shapiro(_resid)%0A%20%20%20%20%20%20%20%20_results.append(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Model%22%3A%20_name%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22n%20(residuals)%22%3A%20len(_resid)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Shapiro-Wilk%20W%22%3A%20f%22%7B_w%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22p-value%22%3A%20%22%3C%200.0001%22%20if%20_p%20%3C%200.0001%20else%20f%22%7B_p%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Reject%20normality%20(%CE%B1%3D0.05)%3F%22%3A%20%22Yes%22%20if%20_p%20%3C%200.05%20else%20%22No%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Interpretation%22%3A%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Residuals%20depart%20significantly%20from%20normality.%20With%20n%20%3E%201%2C000%2C%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Shapiro-Wilk%20is%20highly%20sensitive%20to%20small%20departures.%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Inspect%20Q-Q%20plot%20for%20practical%20significance.%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%20if%20_p%20%3C%200.05%20else%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22No%20significant%20departure%20from%20normality%20detected.%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%7D)%0A%0A%20%20%20%20import%20pandas%20as%20_pd2%0A%20%20%20%20_sw_df%20%3D%20_pd2.DataFrame(_results)%0A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%204.1%20Shapiro-Wilk%20Normality%20Test%20Results%0A%0A%20%20%20%20%20%20%20%20%7Bmo.as_html(_sw_df)%7D%0A%0A%20%20%20%20%20%20%20%20%3E%20**Note%20on%20sample%20size%3A**%20With%20n%20%E2%89%88%202%2C000%20observations%2C%20the%20Shapiro-Wilk%20test%20has%20very%20high%0A%20%20%20%20%20%20%20%20%3E%20statistical%20power%20and%20will%20flag%20even%20minor%2C%20practically%20irrelevant%20deviations%20from%20normality.%0A%20%20%20%20%20%20%20%20%3E%20The%20Q-Q%20plots%20above%20are%20the%20more%20informative%20diagnostic%20at%20this%20sample%20size.%0A%20%20%20%20%20%20%20%20%3E%20If%20residuals%20follow%20approximately%20a%20straight%20line%20on%20the%20Q-Q%20plot%2C%20the%20normality%20assumption%0A%20%20%20%20%20%20%20%20%3E%20is%20reasonably%20satisfied%20for%20inference%20purposes.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%23%204.2%20Robustness%20%E2%80%94%20Standard%20Error%20Strategies%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20model_a%2C%20model_b%2C%20ols_a%2C%20ols_b%2C%20panel_model%2C%20pd%2C%20smf)%3A%0A%20%20%20%20%23%20Compare%20OLS%20%2F%20HC3%20%2F%20clustered-ISO3%20%2F%20year-FE%2Bclustered%20p-values%20per%20predictor%0A%20%20%20%20_FORMULA_A_YFE%20%3D%20(%0A%20%20%20%20%20%20%20%20%22ln_Production%20%20~%20Avg_Temp_C%20%2B%20Rain_mm_country_mean%20%2B%20Rain_mm_within%22%0A%20%20%20%20%20%20%20%20%22%20%2B%20ln_Population%20%2B%20Oil_Price_Brent_USD%20%2B%20C(Year)%22%0A%20%20%20%20)%0A%20%20%20%20_FORMULA_B_YFE%20%3D%20(%0A%20%20%20%20%20%20%20%20%22ln_Export_Value%20~%20Avg_Temp_C%20%2B%20Rain_mm_country_mean%20%2B%20Rain_mm_within%22%0A%20%20%20%20%20%20%20%20%22%20%2B%20ln_Population%20%2B%20Oil_Price_Brent_USD%20%2B%20C(Year)%22%0A%20%20%20%20)%0A%20%20%20%20_yfe_a_raw%20%3D%20smf.ols(_FORMULA_A_YFE%2C%20data%3Dpanel_model).fit()%0A%20%20%20%20_yfe_b_raw%20%3D%20smf.ols(_FORMULA_B_YFE%2C%20data%3Dpanel_model).fit()%0A%0A%20%20%20%20_clust_a%20%20%20%20%20%3D%20ols_a.get_robustcov_results(cov_type%3D%22cluster%22%2C%20groups%3Dpanel_model%5B%22ISO3%22%5D)%0A%20%20%20%20_clust_b%20%20%20%20%20%3D%20ols_b.get_robustcov_results(cov_type%3D%22cluster%22%2C%20groups%3Dpanel_model%5B%22ISO3%22%5D)%0A%20%20%20%20_yfe_clust_a%20%3D%20_yfe_a_raw.get_robustcov_results(cov_type%3D%22cluster%22%2C%20groups%3Dpanel_model%5B%22ISO3%22%5D)%0A%20%20%20%20_yfe_clust_b%20%3D%20_yfe_b_raw.get_robustcov_results(cov_type%3D%22cluster%22%2C%20groups%3Dpanel_model%5B%22ISO3%22%5D)%0A%0A%20%20%20%20_terms%20%20%3D%20%5B%22Avg_Temp_C%22%2C%20%22Rain_mm_country_mean%22%2C%20%22Rain_mm_within%22%2C%20%22ln_Population%22%2C%20%22Oil_Price_Brent_USD%22%5D%0A%20%20%20%20_labels%20%3D%20%5B%22Temp%20(X%E2%82%81)%22%2C%20%22Rainfall-between%20(X%E2%82%82%E2%82%90)%22%2C%20%22Rainfall-within%20(X%E2%82%82%E1%B5%A6)%22%2C%20%22ln(Pop)%20(X%E2%82%83)%22%2C%20%22Oil%20Price%20(X%E2%82%84)%22%5D%0A%0A%20%20%20%20def%20_rob_table(results%2C%20terms%2C%20labels)%3A%0A%20%20%20%20%20%20%20%20rows%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20t%2C%20lbl%20in%20zip(terms%2C%20labels)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20row%20%3D%20%7B%22Term%22%3A%20lbl%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20spec%2C%20res%20in%20results%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_pvals%20%3D%20pd.Series(res.pvalues%2C%20index%3Dres.model.exog_names)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20t%20in%20_pvals.index%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20p%20%3D%20_pvals%5Bt%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sig%20%3D%20%22%20%E2%9C%93%22%20if%20p%20%3C%200.05%20else%20%22%20%E2%9C%97%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row%5Bspec%5D%20%3D%20(%22%3C%200.0001%22%20if%20p%20%3C%200.0001%20else%20f%22%7Bp%3A.4f%7D%22)%20%2B%20sig%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row%5Bspec%5D%20%3D%20%22%E2%80%94%22%0A%20%20%20%20%20%20%20%20%20%20%20%20rows.append(row)%0A%20%20%20%20%20%20%20%20return%20pd.DataFrame(rows)%0A%0A%20%20%20%20_rob_a%20%3D%20_rob_table(%0A%20%20%20%20%20%20%20%20%5B(%22OLS%22%2C%20ols_a)%2C%20(%22HC3%22%2C%20model_a)%2C%20(%22Clustered%22%2C%20_clust_a)%2C%20(%22YFE%2BClustered%22%2C%20_yfe_clust_a)%5D%2C%0A%20%20%20%20%20%20%20%20_terms%2C%20_labels%2C%0A%20%20%20%20)%0A%20%20%20%20_rob_b%20%3D%20_rob_table(%0A%20%20%20%20%20%20%20%20%5B(%22OLS%22%2C%20ols_b)%2C%20(%22HC3%22%2C%20model_b)%2C%20(%22Clustered%22%2C%20_clust_b)%2C%20(%22YFE%2BClustered%22%2C%20_yfe_clust_b)%5D%2C%0A%20%20%20%20%20%20%20%20_terms%2C%20_labels%2C%0A%20%20%20%20)%0A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%23%23%20Model%20A%20%E2%80%94%20ln(Production)%3A%20p-values%20across%20specifications%0A%0A%20%20%20%20%7Bmo.as_html(_rob_a)%7D%0A%0A%20%20%20%20%23%23%23%23%20Model%20B%20%E2%80%94%20ln(Export%20Revenue)%3A%20p-values%20across%20specifications%0A%0A%20%20%20%20%7Bmo.as_html(_rob_b)%7D%0A%0A%20%20%20%20%3E%20**Oil%20price%20(X%E2%82%84)%3A**%20A%20single%20global%20annual%20series%20with%20no%20country-level%20variation.%20In%20the%0A%20%20%20%20%3E%20Year%20FE%20%2B%20Clustered%20specification%2C%20year%20dummies%20absorb%20all%20shared%20time%20movements%2C%20making%0A%20%20%20%20%3E%20the%20oil%20term%20weakly%20identified.%20Its%20coefficient%20in%20that%20column%20is%20a%20macro-time%20residual%2C%0A%20%20%20%20%3E%20not%20a%20country-level%20logistics%20effect%20%E2%80%94%20interpret%20cautiously.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3E%20**%5BConstruct%3A%20Variance%20Estimation%20%26%20Standard%20Errors%5D**%20The%20four%20columns%20above%20represent%20four%0A%20%20%20%20%3E%20different%20variance%20estimation%20strategies%20from%20*%5B%5Bvariance-estimation%5D%5D*%20and%20*%5B%5Bstandard-error%5D%5D*%3A%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20%7C%20Column%20%7C%20SE%20strategy%20%7C%20What%20it%20assumes%20%2F%20corrects%20for%20%7C%0A%20%20%20%20%3E%20%7C--------%7C-------------%7C-------------------------------%7C%0A%20%20%20%20%3E%20%7C%20**OLS**%20%7C%20Classical%20%24%5Chat%7B%5Csigma%7D%5E2%20(X%5ET%20X)%5E%7B-1%7D%24%20%7C%20Homoscedasticity%20%2B%20independence%20%7C%0A%20%20%20%20%3E%20%7C%20**HC3**%20%7C%20Heteroskedasticity-consistent%20(HC3)%20%7C%20Allows%20%24%5Ctext%7BVar%7D(%5Cvarepsilon_i)%20%5Cneq%20%5Csigma%5E2%24%20%E2%80%94%20non-constant%20variance%20%7C%0A%20%20%20%20%3E%20%7C%20**Clustered**%20%7C%20Clustered%20by%20country%20(ISO3)%20%7C%20Allows%20within-country%20correlation%20across%20years%20%7C%0A%20%20%20%20%3E%20%7C%20**YFE%2BClustered**%20%7C%20Year%20dummies%20%2B%20clustered%20%7C%20Also%20absorbs%20shared%20global%20time%20trends%20%7C%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20**What%20to%20look%20for%3A**%20A%20predictor%20that%20is%20significant%20(%E2%9C%93)%20in%20*all%20four*%20columns%20is%20the%20most%0A%20%20%20%20%3E%20convincing%20result%20%E2%80%94%20its%20significance%20is%20not%20an%20artifact%20of%20the%20assumed%20error%20structure.%0A%20%20%20%20%3E%20A%20predictor%20that%20flips%20from%20%E2%9C%93%20to%20%E2%9C%97%20between%20OLS%20and%20HC3%20had%20inflated%20significance%20due%20to%0A%20%20%20%20%3E%20heteroskedasticity.%20A%20predictor%20that%20flips%20under%20Clustered%20was%20riding%20on%20within-country%0A%20%20%20%20%3E%20autocorrelation%20rather%20than%20a%20true%20cross-country%20relationship.%0A%20%20%20%20%3E%0A%20%20%20%20%3E%20OLS%20assumes%20homoscedastic%2C%20independent%20errors%3B%20%24%5Chat%7B%5Csigma%7D%5E2%20%3D%20MS_E%20%3D%20SS_E%20%2F%20(n-k-1)%24%0A%20%20%20%20%3E%20(the%20same%20%24MS_E%24%20that%20anchors%20all%20CI%20and%20t-test%20formulas).%20When%20that%20assumption%20fails%2C%0A%20%20%20%20%3E%20HC3%20or%20clustered%20corrections%20prevent%20over-confident%20inferences.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%23%204.3%20Influence%20Diagnostics%20%E2%80%94%20Leverage%2C%20Cook's%20Distance%2C%20Studentized%20Residuals%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20ols_a%2C%20ols_b%2C%20panel_model%2C%20pd)%3A%0A%20%20%20%20import%20pycountry%0A%20%20%20%20from%20statsmodels.stats.outliers_influence%20import%20OLSInfluence%0A%0A%20%20%20%20def%20_iso3_to_name(code)%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20pycountry.countries.get(alpha_3%3Dcode).name%0A%20%20%20%20%20%20%20%20except%20AttributeError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20code%0A%0A%20%20%20%20def%20_build_diag(ols_result%2C%20panel_df)%3A%0A%20%20%20%20%20%20%20%20infl%20%3D%20OLSInfluence(ols_result)%0A%20%20%20%20%20%20%20%20n%20%3D%20int(ols_result.nobs)%0A%20%20%20%20%20%20%20%20p%20%3D%20int(ols_result.df_model)%20%2B%201%0A%20%20%20%20%20%20%20%20df%20%3D%20pd.DataFrame(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Country%22%3A%20%20%5B_iso3_to_name(c)%20for%20c%20in%20panel_df%5B%22ISO3%22%5D.values%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Year%22%3A%20%20%20%20%20panel_df%5B%22Year%22%5D.values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22rstudent%22%3A%20infl.resid_studentized_external%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22leverage%22%3A%20infl.hat_matrix_diag%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22cooks_d%22%3A%20%20infl.cooks_distance%5B0%5D%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20df%5B%22high_leverage%22%5D%20%3D%20df%5B%22leverage%22%5D%20%3E%202%20*%20p%20%2F%20n%0A%20%20%20%20%20%20%20%20df%5B%22outlier%22%5D%20%20%20%20%20%20%20%3D%20df%5B%22rstudent%22%5D.abs()%20%3E%203%0A%20%20%20%20%20%20%20%20df%5B%22influential%22%5D%20%20%20%3D%20df%5B%22cooks_d%22%5D%20%3E%200.5%0A%20%20%20%20%20%20%20%20return%20df%2C%20n%2C%20p%0A%0A%20%20%20%20diag_a%2C%20_n_a%2C%20_p_a%20%3D%20_build_diag(ols_a%2C%20panel_model)%0A%20%20%20%20diag_b%2C%20_n_b%2C%20_p_b%20%3D%20_build_diag(ols_b%2C%20panel_model)%0A%0A%20%20%20%20def%20_top10(df%2C%20label)%3A%0A%20%20%20%20%20%20%20%20_t%20%3D%20df.nlargest(10%2C%20%22cooks_d%22)%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B%22Country%22%2C%20%22Year%22%2C%20%22rstudent%22%2C%20%22leverage%22%2C%20%22cooks_d%22%2C%20%22high_leverage%22%2C%20%22outlier%22%2C%20%22influential%22%5D%0A%20%20%20%20%20%20%20%20%5D.copy()%0A%20%20%20%20%20%20%20%20for%20c%20in%20%5B%22rstudent%22%2C%20%22leverage%22%2C%20%22cooks_d%22%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_t%5Bc%5D%20%3D%20_t%5Bc%5D.map(lambda%20x%3A%20f%22%7Bx%3A.4f%7D%22)%0A%20%20%20%20%20%20%20%20_t.insert(0%2C%20%22Model%22%2C%20label)%0A%20%20%20%20%20%20%20%20return%20_t%0A%0A%20%20%20%20_top_df%20%3D%20pd.concat(%5B_top10(diag_a%2C%20%22A%22)%2C%20_top10(diag_b%2C%20%22B%22)%5D%2C%20ignore_index%3DTrue)%0A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%23%23%20Top%2010%20influential%20observations%20by%20Cook's%20D%0A%0A%20%20%20%20%7Bmo.as_html(_top_df)%7D%0A%0A%20%20%20%20%3E%20Thresholds%3A%20leverage%20%3E%202p%2Fn%20(%7B2*_p_a%2F_n_a%3A.4f%7D%20for%20A%2C%20%7B2*_p_b%2F_n_b%3A.4f%7D%20for%20B)%3B%0A%20%20%20%20%3E%20outlier%20%3D%20%7Crstudent%7C%20%3E%203%3B%20influential%20%3D%20Cook's%20D%20%3E%200.5.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%20diag_a%2C%20diag_b%0A%0A%0A%40app.cell%0Adef%20_(ACCENT%2C%20ACCENT2%2C%20diag_a%2C%20diag_b%2C%20mo%2C%20ols_a%2C%20ols_b%2C%20plt)%3A%0A%20%20%20%20def%20_()%3A%0A%20%20%20%20%20%20%20%20fig_inf%2C%20axes_inf%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(14%2C%204))%0A%20%20%20%20%20%20%20%20fig_inf.suptitle(%22Cook's%20Distance%20%E2%80%94%20Influence%20Diagnostics%22%2C%20fontsize%3D13%2C%20fontweight%3D%22bold%22)%0A%0A%20%20%20%20%20%20%20%20for%20ax%2C%20diag%2C%20color%2C%20label%2C%20n%20in%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(axes_inf%5B0%5D%2C%20diag_a%2C%20ACCENT%2C%20%20%22Model%20A%20%E2%80%94%20ln(Production)%22%2C%20%20%20%20int(ols_a.nobs))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(axes_inf%5B1%5D%2C%20diag_b%2C%20ACCENT2%2C%20%22Model%20B%20%E2%80%94%20ln(Export%20Revenue)%22%2C%20int(ols_b.nobs))%2C%0A%20%20%20%20%20%20%20%20%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.bar(range(len(diag))%2C%20diag%5B%22cooks_d%22%5D%2C%20color%3Dcolor%2C%20alpha%3D0.5%2C%20width%3D1.0%2C%20linewidth%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.axhline(0.5%2C%20%20%20color%3D%22red%22%2C%20%20%20%20linewidth%3D1.2%2C%20linestyle%3D%22--%22%2C%20label%3D%22D%20%3D%200.5%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.axhline(4%20%2F%20n%2C%20color%3D%22orange%22%2C%20linewidth%3D1.0%2C%20linestyle%3D%22--%22%2C%20label%3Df%224%2Fn%20%3D%20%7B4%2Fn%3A.4f%7D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_title(label)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_xlabel(%22Observation%20index%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.set_ylabel(%22Cook's%20D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.legend(fontsize%3D8)%0A%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%20%20%20%20%20%20%20%20return%20mo.mpl.interactive(fig_inf)%0A%0A%20%20%20%20_()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%205%20%C2%B7%20Conclusions%0A%0A%20%20%20%20%23%23%23%205.1%20Correlation%20Analysis%20Summary%0A%0A%20%20%20%20For%20each%20of%20the%208%20Pearson%20correlation%20tests%20at%20**%CE%B1%20%3D%200.05**%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(corr_df%2C%20mo%2C%20pd)%3A%0A%20%20%20%20%23%20Build%20a%20plain-English%20conclusion%20table%0A%20%20%20%20_conclusions%20%3D%20%5B%5D%0A%20%20%20%20for%20_%2C%20row%20in%20corr_df.iterrows()%3A%0A%20%20%20%20%20%20%20%20r%20%3D%20float(row%5B%22r%22%5D)%0A%20%20%20%20%20%20%20%20p%20%3D%20float(row%5B%22p-value%22%5D)%0A%20%20%20%20%20%20%20%20reject%20%3D%20p%20%3C%200.05%0A%20%20%20%20%20%20%20%20direction%20%3D%20%22positive%22%20if%20r%20%3E%200%20else%20%22negative%22%0A%20%20%20%20%20%20%20%20strength%20%3D%20%22weak%22%20if%20abs(r)%20%3C%200.2%20else%20(%22moderate%22%20if%20abs(r)%20%3C%200.5%20else%20%22strong%22)%0A%0A%20%20%20%20%20%20%20%20if%20reject%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20text%20%3D%20(f%22Reject%20H%E2%82%80.%20Statistically%20significant%20%7Bdirection%7D%20linear%20relationship%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22(r%20%3D%20%7Br%3A.3f%7D%2C%20%7Bstrength%7D).%20At%20%CE%B1%20%3D%200.05%2C%20there%20is%20sufficient%20evidence%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22that%20%CF%81%20%E2%89%A0%200.%22)%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20text%20%3D%20(f%22Fail%20to%20reject%20H%E2%82%80.%20Insufficient%20evidence%20of%20a%20linear%20relationship%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22(r%20%3D%20%7Br%3A.3f%7D%2C%20p%20%3D%20%7Bp%3A.3f%7D).%20Cannot%20conclude%20%CF%81%20%E2%89%A0%200%20at%20%CE%B1%20%3D%200.05.%22)%0A%0A%20%20%20%20%20%20%20%20_conclusions.append(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Pair%22%3A%20f%22%7Brow%5B'Predictor'%5D%7D%20%E2%86%92%20%7Brow%5B'Response'%5D%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22r%22%3A%20f%22%7Br%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22p-value%22%3A%20%22%3C%200.0001%22%20if%20p%20%3C%200.0001%20else%20f%22%7Bp%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Conclusion%22%3A%20text%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%0A%20%20%20%20_conc_df%20%3D%20pd.DataFrame(_conclusions)%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%23%23%20Plain-English%20Conclusions%0A%0A%20%20%20%20%7Bmo.as_html(_conc_df)%7D%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20model_a%2C%20model_b)%3A%0A%20%20%20%20%23%20Regression%20conclusion%20text%0A%20%20%20%20_all_terms%20%3D%20%5B%22Avg_Temp_C%22%2C%20%22Rain_mm_country_mean%22%2C%20%22Rain_mm_within%22%2C%20%22ln_Population%22%2C%20%22Oil_Price_Brent_USD%22%5D%0A%20%20%20%20_a_sig%20%3D%20%5Bt%20for%20t%20in%20_all_terms%20if%20model_a.pvalues%5Bt%5D%20%3C%200.05%5D%0A%20%20%20%20_b_sig%20%3D%20%5Bt%20for%20t%20in%20_all_terms%20if%20model_b.pvalues%5Bt%5D%20%3C%200.05%5D%0A%0A%20%20%20%20_name_map%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22Avg_Temp_C%22%3A%20%20%20%20%20%20%20%20%20%20%20%22Temperature%22%2C%0A%20%20%20%20%20%20%20%20%22Rain_mm_country_mean%22%3A%20%22Rainfall-between%22%2C%0A%20%20%20%20%20%20%20%20%22Rain_mm_within%22%3A%20%20%20%20%20%20%20%22Rainfall-within%22%2C%0A%20%20%20%20%20%20%20%20%22ln_Population%22%3A%20%20%20%20%20%20%20%20%22ln(Population)%22%2C%0A%20%20%20%20%20%20%20%20%22Oil_Price_Brent_USD%22%3A%20%20%22Oil%20Price%22%2C%0A%20%20%20%20%7D%0A%0A%20%20%20%20def%20_p_str(p)%3A%0A%20%20%20%20%20%20%20%20return%20%22%3C%200.0001%22%20if%20p%20%3C%200.0001%20else%20f%22%3D%20%7Bp%3A.4f%7D%22%0A%0A%20%20%20%20def%20_predictor_phrasings(sig_terms%2C%20model%2C%20response_label)%3A%0A%20%20%20%20%20%20%20%20if%20not%20sig_terms%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22-%20No%20individually%20significant%20predictors%20at%20%CE%B1%20%3D%200.05.%22%0A%20%20%20%20%20%20%20%20lines%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20t%20in%20sig_terms%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20p%20%3D%20model.pvalues%5Bt%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20lines.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22-%20**%7B_name_map%5Bt%5D%7D%3A**%20p-value%20%7B_p_str(p)%7D%20%3C%20%CE%B1%20%3D%200.05.%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22We%20reject%20H%E2%82%80%3A%20%CE%B2%20%3D%200.%20There%20is%20sufficient%20evidence%20that%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22%7B_name_map%5Bt%5D%7D%20is%20a%20significant%20predictor%20of%20%7Bresponse_label%7D.%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20return%20%22%5Cn%22.join(lines)%0A%0A%20%20%20%20_a_fp%20%3D%20_p_str(model_a.f_pvalue)%0A%20%20%20%20_b_fp%20%3D%20_p_str(model_b.f_pvalue)%0A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%205.2%20Regression%20Summary%0A%0A%20%20%20%20%20%20%20%20**Model%20A%20%E2%80%94%20ln(Production)%3A**%20R%C2%B2%20%3D%20%7Bmodel_a.rsquared%3A.4f%7D%2C%20Adj.%20R%C2%B2%20%3D%20%7Bmodel_a.rsquared_adj%3A.4f%7D%0A%0A%20%20%20%20%20%20%20%20Overall%20F-test%3A%20F%E2%82%80%20%3D%20%7Bmodel_a.fvalue%3A.2f%7D%2C%20p-value%20%7B_a_fp%7D%20%3C%20%CE%B1%20%3D%200.05.%0A%20%20%20%20%20%20%20%20We%20reject%20H%E2%82%80%3A%20%CE%B2%E2%82%81%20%3D%20%CE%B2%E2%82%82%20%3D%20%CE%B2%E2%82%83%20%3D%20%CE%B2%E2%82%84%20%3D%200.%20There%20is%20sufficient%20evidence%20that%20the%20model%20has%20statistically%20significant%20explanatory%20power.%0A%20%20%20%20%20%20%20%20**%7Bmodel_a.rsquared_adj%20*%20100%3A.1f%7D%25%20of%20the%20variation%20in%20ln(Production)%20is%20explained%20by%20the%20regression%20model**%20(adj.%20R%C2%B2).%0A%0A%20%20%20%20%20%20%20%20Individually%20significant%20predictors%20(%CE%B1%20%3D%200.05)%3A%0A%0A%20%20%20%20%20%20%20%20%7B_predictor_phrasings(_a_sig%2C%20model_a%2C%20%22ln(Production)%22)%7D%0A%0A%20%20%20%20%20%20%20%20---%0A%0A%20%20%20%20%20%20%20%20**Model%20B%20%E2%80%94%20ln(Export%20Revenue)%3A**%20R%C2%B2%20%3D%20%7Bmodel_b.rsquared%3A.4f%7D%2C%20Adj.%20R%C2%B2%20%3D%20%7Bmodel_b.rsquared_adj%3A.4f%7D%0A%0A%20%20%20%20%20%20%20%20Overall%20F-test%3A%20F%E2%82%80%20%3D%20%7Bmodel_b.fvalue%3A.2f%7D%2C%20p-value%20%7B_b_fp%7D%20%3C%20%CE%B1%20%3D%200.05.%0A%20%20%20%20%20%20%20%20We%20reject%20H%E2%82%80%3A%20%CE%B2%E2%82%81%20%3D%20%CE%B2%E2%82%82%20%3D%20%CE%B2%E2%82%83%20%3D%20%CE%B2%E2%82%84%20%3D%200.%20There%20is%20sufficient%20evidence%20that%20the%20model%20has%20statistically%20significant%20explanatory%20power.%0A%20%20%20%20%20%20%20%20**%7Bmodel_b.rsquared_adj%20*%20100%3A.1f%7D%25%20of%20the%20variation%20in%20ln(Export%20Revenue)%20is%20explained%20by%20the%20regression%20model**%20(adj.%20R%C2%B2).%0A%0A%20%20%20%20%20%20%20%20Individually%20significant%20predictors%20(%CE%B1%20%3D%200.05)%3A%0A%0A%20%20%20%20%20%20%20%20%7B_predictor_phrasings(_b_sig%2C%20model_b%2C%20%22ln(Export%20Revenue)%22)%7D%0A%0A%20%20%20%20%20%20%20%20---%0A%0A%20%20%20%20%20%20%20%20%23%23%23%205.3%20Limitations%0A%0A%20%20%20%20%20%20%20%201.%20**Rainfall%20is%20largely%20structural%3A**%2082.5%25%20of%20country-year%20rows%20carry%20a%20fixed%20climatological%0A%20%20%20%20%20%20%20%20%20%20%20mean%20for%20rainfall%20%E2%80%94%20the%20value%20does%20not%20vary%20year%20to%20year.%20Rainfall%20reflects%20cross-country%0A%20%20%20%20%20%20%20%20%20%20%20differences%20in%20climate%20zone%20rather%20than%20year-to-year%20variation.%20Its%20coefficient%20should%20be%0A%20%20%20%20%20%20%20%20%20%20%20interpreted%20as%20a%20structural%20climate%20effect%2C%20not%20a%20dynamic%20one.%0A%0A%20%20%20%20%20%20%20%202.%20**Omitted%20variables%3A**%20Altitude%2C%20soil%20type%2C%20variety%20(Arabica%20vs.%20Robusta)%2C%20political%0A%20%20%20%20%20%20%20%20%20%20%20stability%2C%20and%20agricultural%20subsidies%20are%20all%20known%20drivers%20of%20production%20that%20are%20not%0A%20%20%20%20%20%20%20%20%20%20%20included%20in%20this%20model.%0A%0A%20%20%20%20%20%20%20%203.%20**Correlation%20%E2%89%A0%20causation%3A**%20This%20is%20a%20cross-sectional%20panel%20analysis.%20Statistically%0A%20%20%20%20%20%20%20%20%20%20%20significant%20correlations%20document%20co-variation%20across%20countries%20and%20years%20but%20do%20not%0A%20%20%20%20%20%20%20%20%20%20%20establish%20causal%20mechanisms.%0A%0A%20%20%20%20%20%20%20%204.%20**Oil%20price%20is%20global%3A**%20A%20single%20annual%20Brent%20price%20is%20assigned%20to%20all%20countries.%20This%0A%20%20%20%20%20%20%20%20%20%20%20cannot%20capture%20country-specific%20exposure%20to%20fuel%20and%20fertilizer%20costs.%0A%0A%20%20%20%20%20%20%20%205.%20**Panel%20is%20unbalanced%3A**%20Not%20every%20country%20appears%20in%20every%20year.%20This%20could%20introduce%0A%20%20%20%20%20%20%20%20%20%20%20selection%20effects%20if%20data%20availability%20is%20correlated%20with%20production%20levels.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20---%0A%20%20%20%20%23%23%20Data%20Sources%0A%0A%20%20%20%20%7C%20Source%20%7C%20Description%20%7C%20Coverage%20%7C%0A%20%20%20%20%7C---%7C---%7C---%7C%0A%20%20%20%20%7C%20%5BFAOSTAT%20QCL%5D(https%3A%2F%2Fwww.fao.org%2Ffaostat%2Fen%2F%23data%2FQCL)%20%7C%20Coffee%20production%20(tonnes)%2C%20item%20656%20%22Coffee%2C%20green%22%20%7C%201961%E2%80%932024%20%7C%0A%20%20%20%20%7C%20%5BBACI%2FCEPII%5D(https%3A%2F%2Fwww.cepii.fr%2FCEPII%2Fen%2Fbdd_modele%2Fbdd_modele_item.asp%3Fid%3D37)%20%7C%20Harmonized%20bilateral%20coffee%20trade%20flows%20%7C%201995%E2%80%932024%20%7C%0A%20%20%20%20%7C%20%5BBerkeley%20Earth%5D(https%3A%2F%2Fberkeleyearth.org)%20%2F%20%5BERA5%5D(https%3A%2F%2Fwww.ecmwf.int)%20%7C%20Country%20annual%20avg%20temperature%20(%C2%B0C)%20%7C%201995%E2%80%932024%20%7C%0A%20%20%20%20%7C%20%5BWorld%20Bank%20%2F%20ERA5-Land%5D(https%3A%2F%2Fdata.worldbank.org)%20%7C%20Country%20annual%20avg%20rainfall%20(mm%2Fyr)%20%7C%201995%E2%80%932024%20%7C%0A%20%20%20%20%7C%20%5BWorld%20Bank%5D(https%3A%2F%2Fdata.worldbank.org%2Findicator%2FSP.POP.TOTL)%20%7C%20Annual%20population%20%7C%201995%E2%80%932024%20%7C%0A%20%20%20%20%7C%20Various%20(Brent%20crude)%20%7C%20Annual%20avg%20oil%20price%20(USD%2Fbbl)%20%7C%201995%E2%80%932024%20%7C%0A%0A%20%20%20%20Full%20column-level%20documentation%3A%20%5B%60data%2Fcoffee_analysis_panel_with_covariates_data_dictionary.md%60%5D(..%2Fdata%2Fcoffee_analysis_panel_with_covariates_data_dictionary.md)%0A%0A%20%20%20%20---%0A%20%20%20%20*INEG%202314H%20%E2%80%94%20Statistics%20for%20Industrial%20Engineers%20%C2%B7%20Warren%20Ross%20%C2%B7%202026*%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
59968406afcc504f35d420378facccf4