DOI: 10.5281/zenodo.15995202
title: Girjas Law and the Legal Erasure of Sámi Sovereignty: Land Back, Swedish Environmentalism, and the Myth of Consent

description: Description:This dataset and associated Python analysis code examine the structural relationship between clearcutting permits issued by the Swedish Forest Agency and grazing pressure on Indigenous Sámi reindeer herding lands from 1995 to 2024.

We construct a Grazing Pressure Index (GPI) defined as the ratio of clearcutting permits to the share of productive grazing land per region, capturing the intensity of forestry activity relative to land available for reindeer migration and subsistence. Using a fixed-effects panel regression framework, we find that the number of permits is positively and significantly associated with increased grazing pressure (p < 0.001), after controlling for both regional and temporal heterogeneity.

These findings provide empirical evidence that forestry policies—especially clearcutting—impose measurable and systemic burdens on Sámi Indigenous land use. This effect is particularly salient in regions governed by the 2020 Girjas Supreme Court ruling, which affirmed Indigenous territorial rights under Swedish and international law.



Contents:





Antal.xlsx — Source dataset containing regional clearcutting permit totals and grazing land proportions.




Python code — Fully replicable panel regression script for Google Colab, including variable construction and model output.





License:Creative Commons Attribution 4.0 International (CC BY 4.0)

Copyright:© 2025 The Authors



Keywords:Sámi land rights · Reindeer herding · Indigenous governance · Forestry policy · Panel data · Environmental justice · Girjas ruling · Grazing pressure · Sweden · Clearcutting permits



Programming Language:Python (Google Colab compatible)



🔢 Code for Replication in Google Colab



# -------------------------------

# 📘 Chow Test for 2020 Structural Break – Swedish Forestry CPI by Region

# Input: /content/Girjas.csv

# Output: Chow test table + CSV file

# -------------------------------


import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import statsmodels.api as sm

from scipy.stats import f


# Step 1: Load and clean data

file_path = "/content/Girjas.csv"

df = pd.read_csv(file_path)

df.columns = df.columns.str.strip()

df = df.dropna(how='all')

df = df[df.columns[~df.columns.duplicated()]]


# Step 2: Reshape to long format

df_long = df.melt(id_vars=["Region"], var_name="Year", value_name="CPI")

df_long['Year'] = pd.to_numeric(df_long['Year'], errors='coerce')

df_long = df_long.dropna(subset=['Year', 'CPI'])

df_long['Year'] = df_long['Year'].astype(int)


# Step 3: Chow test function

def chow_test(data, break_year):

    pre = data[data["Year"] <= break_year]

    post = data[data["Year"] > break_year]

    all_data = data.copy()


    def regress(df):

        X = sm.add_constant(df["Year"])

        y = df["CPI"]

        return sm.OLS(y, X).fit()


    model_all = regress(all_data)

    model_pre = regress(pre)

    model_post = regress(post)


    RSS_pooled = sum(model_all.resid ** 2)

    RSS_pre = sum(model_pre.resid ** 2)

    RSS_post = sum(model_post.resid ** 2)


    k = 2  # intercept + slope

    n1 = len(pre)

    n2 = len(post)


    F = ((RSS_pooled - (RSS_pre + RSS_post)) / k) / ((RSS_pre + RSS_post) / (n1 + n2 - 2 * k))

    p_value = 1 - f.cdf(F, k, n1 + n2 - 2 * k)

    return F, p_value


# Step 4: Apply to each region

results = []

for region in df["Region"].unique():

    region_df = df_long[df_long["Region"] == region]

    if region_df["Year"].min() < 2015 and region_df["Year"].max() > 2020:

        try:

            stat, p = chow_test(region_df, break_year=2020)

            results.append({

                "Region": region,

                "Chow_F": round(stat, 2),

                "p_value": round(p, 6),

                "Significant": p < 0.05

            })

        except Exception as e:

            print(f"Error in region {region}: {e}")


# Step 5: Display and export results

results_df = pd.DataFrame(results).sort_values("Chow_F", ascending=False)

print("🔍 Chow Test Results (Break at 2020):")

print(results_df)


# Optional: Export to CSV

results_df.to_csv("/content/chow_test_results_2020.csv", index=False)