1 What this document does

Prepares the ground for everything else: checks the working directory, loads the required packages, creates the output folders, reads the raw data, and defines the constants shared by all later documents.

It produces no results. Run it first, every time.

The last chunk saves the constants to output/clean/00_setup.RData, so later documents begin with one line:

load("output/clean/00_setup.RData")

The raw data is read here to confirm it is present and to report its shape, but it is not re-saved - 01_prepare_data.Rmd reads the original file directly (it takes under a second) and saves the filtered result. This keeps the intermediate files small.

How to run: open PKP.Rproj in RStudio, open this file, and knit it (or run the chunks in order).


2 Are we in the right place?

All paths are relative to the project root - the folder containing Data/. Opening PKP.Rproj guarantees this. If it is wrong, stop immediately with a clear message rather than failing confusingly twenty lines later.

if (!dir.exists("Data")) {
  stop(
    "Working directory is not the project root.\n",
    "  Currently in: ", getwd(), "\n",
    "  Fix: open PKP.Rproj in RStudio.",
    call. = FALSE
  )
}

getwd()
## [1] "/Users/aljaz/Desktop/PKP/PKP-Analysis"

3 Packages

Deliberately kept to two, both near-universal, so this is unlikely to fail on another machine. Nothing is installed automatically - if a package is missing, the user is told exactly what to run.

required_packages <- c("dplyr", "ggplot2")

missing_packages <- required_packages[
  !required_packages %in% rownames(installed.packages())
]

if (length(missing_packages) > 0) {
  stop(
    "Missing required package(s): ", paste(missing_packages, collapse = ", "), "\n",
    "  Please run:\n",
    '  install.packages(c("', paste(missing_packages, collapse = '", "'), '"))',
    call. = FALSE
  )
}

suppressPackageStartupMessages({
  library(dplyr)
  library(ggplot2)
})

4 Output folders

Created if absent, silent if already there. Nothing is ever deleted.

Note the folder is output/clean, not data/clean. Writing to data/ would collide with the existing Data/ source folder on case-insensitive filesystems (macOS, Windows) while creating a separate folder on Linux - the same script behaving differently on different machines. All generated files stay under output/, so the source data is never touched.

output_dirs <- c("output", "output/tables", "output/figures", "output/clean")

for (d in output_dirs) {
  if (!dir.exists(d)) dir.create(d, recursive = TRUE)
}

list.dirs("output")
## [1] "output"         "output/clean"   "output/figures" "output/tables"

5 Read the raw data

Source: EUKLEMS & INTANProd (LUISS). Two objects:

  • klems - industry x country x year, 1995-2021. The working dataset.
  • annual - country x year, total economy, 2010-2025. Macro context only.
raw_data_file <- "Data/Luiss_datasets.RData"

if (!file.exists(raw_data_file)) {
  stop("Raw data not found at: ", raw_data_file, call. = FALSE)
}

load(raw_data_file)

# `annual$year` arrives as text; make it a number so it sorts and joins correctly
annual$year <- as.integer(annual$year)

dim(klems)
## [1] 61128   236
dim(annual)
## [1] 495  35

6 Project constants

Defined once here so every later document uses the same definitions, and so a reviewer can see all the analytical choices in one place. Each choice follows from the data exploration in data_exploration.Rmd.

# An EXPLICIT list, never a pattern. Matching on first letter would also capture
# MARKT, MARKTxAG and M-N, which are economy-wide aggregates, not section M.
# All other codes are excluded deliberately: the industry column mixes four
# levels of one hierarchy, and summing across it overstates the Slovenian
# economy by a factor of 5.4.
focus_sections <- c("C", "G", "H", "I", "J", "M")

industry_labels <- c(
  C = "Manufacturing",
  G = "Trade and repair of motor vehicles",
  H = "Transport and storage",
  I = "Accommodation and food service",
  J = "Information and communication",
  M = "Professional, scientific and technical"
)

industry_groups <- c(
  J = "Knowledge-intensive",
  M = "Knowledge-intensive",
  G = "Traditional",
  H = "Traditional",
  I = "Traditional",
  C = "Manufacturing"
)

6.1 Division-level codes

The mentors asked for detail down to division (two-digit) level. The data supports this only partly: below section level Slovenia has value added and the LUISS-estimated economic competencies, but no national-accounts investment and no growth accounting. Sections I and M have no divisions at all in this database.

The list below is non-overlapping. C20-C21 and C26-C27 are deliberately excluded because they duplicate C20, C21, C26 and C27; C0-C21 and C6-C27 are excluded because they are unlabelled (and absent for Slovenia).

division_parent <- c(
  # C - manufacturing (13 divisions, no overlaps)
  "C10-C12" = "C", "C13-C15" = "C", "C16-C18" = "C", "C19" = "C",
  "C20" = "C", "C21" = "C", "C22-C23" = "C", "C24-C25" = "C",
  "C26" = "C", "C27" = "C", "C28" = "C", "C29-C30" = "C", "C31-C33" = "C",
  # G - trade
  "G45" = "G", "G46" = "G", "G47" = "G",
  # H - transport
  "H49" = "H", "H50" = "H", "H51" = "H", "H52" = "H", "H53" = "H",
  # J - information and communication
  "J58-J60" = "J", "J61" = "J", "J62-J63" = "J"
  # I and M have no divisions in this database
)

division_codes <- names(division_parent)

length(division_codes)
## [1] 24
table(division_parent)
## division_parent
##  C  G  H  J 
## 13  3  5  3

6.2 Why the country groups are what they are

These groupings are our own decision, not a standard from the literature. The regional labels are conventional in European comparative work, but no source defines these particular memberships, and they should be described in the chapter as a choice we made rather than a convention we followed.

What is sourced. The inclusion threshold and the exclusions are driven by the data. The EU15 / new-member-state split that the four regions nest into is a standard, dateable division. Bontadini, Corrado, Haskel, Iommi & Jona-Lasinio (2023) use an EU11 aggregate; ours is not that aggregate, and where theirs is cited the difference is stated.

What is ours. Which countries sit in which region, the decision to use six groups rather than two, and the placement of the United Kingdom outside the EU.

Why we grouped this way. Reporting twenty-one countries individually is unreadable, and a single EU average hides the variation the chapter is about - Slovenia’s position relative to other catching-up economies is a different question from its position relative to Germany. Regional groups keep the comparison legible while preserving that distinction, and because they nest inside the EU15 / new-member-state split, results can be reported at either level without recomputing anything.

The United Kingdom is placed outside the EU because it is no longer a member. This departs from the literature, whose EU aggregates were defined while it was. The departure is deliberate and is stated wherever an EU aggregate is reported.

What we considered and did not adopt. Grouping by accession cohort (2004 against 2007) is objective but legal rather than economic. Grouping by euro-area membership is objective and relevant to financing conditions, and remains available as a robustness check. Grouping by economic structure - manufacturing share of value added - would be data-driven and directly relevant, and is the strongest alternative. Grouping by intangible intensity was rejected outright as circular: it would sort countries by the variable the chapter then compares.

Known weakness. “Central and Eastern” contains three arguably distinct economies: the Baltic states (LT, LV), the Visegrad industrial economies (CZ, SK) and the later-acceding south-east (BG, RO). They are grouped together to keep the group large enough that one country does not drive the average. Splitting them gives more accurate labels and less reliable means; that trade-off is a judgement, and a reader may reasonably prefer the other side of it.

# COUNTRY GROUPS
#
# --- Inclusion rule -------------------------------------------------------
# A country is included if it has BOTH tangible and intangible investment for
# at least 80 percent of the 162 possible observations (6 focus sections x 27
# years), i.e. at least 130.
#
# The bar is set at 80 percent rather than at complete coverage because
# Slovenia itself is not complete: 162 tangible but 144 intangible, the gap
# being transport (H) before 2006. Requiring completeness would exclude
# comparators that are better covered than the subject of the study.
#
# Twenty countries qualify. Excluded, with the reason:
#   BE 162/0     tangible only, no intangible investment in this release
#   EL 0/162     intangible only, no tangible
#   HU 0/162     intangible only
#   EE 0/159     intangible only
#   MT 128/146   tangible below the threshold
#   PT 72/72     both far below
#   CY, HR, IE, PL   no investment data at all
# All of these DO have total-economy intangible investment in the `annual`
# table (2010-2025). The restriction applies to the industry analysis only.
#
# --- Grouping -------------------------------------------------------------
# EU comparators are split into four regional groups. The typology is the
# conventional one in European comparative work - Nordic, Continental,
# Southern, Central and Eastern - rather than one specific paper's.
#
# It nests exactly inside the standard EU15 / new-member-state split:
#   Nordic + Continental + Southern = the EU15 members in the sample
#   Central and Eastern             = the post-2004 accession members
# so results can be reported at either level of aggregation.
#
# The United Kingdom is treated as NON-EU. Note this departs from Bontadini,
# Corrado, Haskel, Iommi & Jona-Lasinio (2023), whose EU11 aggregate includes
# the UK because it was defined while the UK was a member. Where their EU11 is
# cited, that difference must be stated.

country_groups <- list(
  slovenia    = "SI",
  nordic      = c("DK", "FI", "SE"),
  continental = c("AT", "DE", "FR", "LU", "NL"),
  southern    = c("ES", "IT"),
  cee         = c("BG", "CZ", "LT", "LV", "RO", "SK"),
  non_eu      = c("UK", "US", "JP")
)

group_names <- c(slovenia    = "Slovenia",
                 nordic      = "Nordic",
                 continental = "Continental",
                 southern    = "Southern",
                 cee         = "Central and Eastern",
                 non_eu      = "Non-EU")

peer_countries <- unlist(country_groups, use.names = FALSE)

# Aggregates, for reporting at a coarser level
eu_comparators  <- unlist(country_groups[c("nordic","continental","southern","cee")],
                          use.names = FALSE)          # 16 EU countries, excluding SI
eu15_comparators <- unlist(country_groups[c("nordic","continental","southern")],
                          use.names = FALSE)          # 10 pre-2004 members
nms_comparators  <- country_groups$cee                # 6 post-2004 members
non_eu           <- country_groups$non_eu             # UK, US, JP

# Growth-accounting benchmark. No EU aggregate in the database carries the
# intangible investment variables, so the EU comparison for investment must be
# built from member states. For growth accounting the EU11 code does carry data,
# but its composition ("EU12 without UK") is not the EU11 of the paper, so its
# actual membership must be stated wherever it is used.
ga_benchmark <- "EU11"

c(total = length(peer_countries), EU = length(eu_comparators),
  EU15 = length(eu15_comparators), NMS = length(nms_comparators),
  non_EU = length(non_eu))
##  total     EU   EU15    NMS non_EU 
##     20     16     10      6      3
# The file claims 1995-2021, but coverage differs by variable. The chapter must
# state each period explicitly rather than implying full coverage.
periods <- list(
  flows         = c(1995, 2021),
  stocks        = c(2000, 2021),
  contributions = c(2001, 2021),
  tfp           = c(2009, 2021)
)

periods
## $flows
## [1] 1995 2021
## 
## $stocks
## [1] 2000 2021
## 
## $contributions
## [1] 2001 2021
## 
## $tfp
## [1] 2009 2021

7 Figure style

The style guide requires black and white only - no colour is available in the printed book. Defined here so every figure in the project is consistent.

theme_pkp <- function(base_size = 11) {
  theme_bw(base_size = base_size) +
    theme(
      panel.grid.minor = element_blank(),
      panel.grid.major = element_line(colour = "grey85", linewidth = 0.3),
      panel.border     = element_rect(colour = "black", linewidth = 0.4),
      strip.background = element_rect(fill = "grey92", colour = "black"),
      legend.position  = "bottom",
      legend.title     = element_blank(),
      plot.title       = element_text(face = "bold", size = base_size)
    )
}

grey_palette <- c("black", "grey45", "grey70", "grey25", "grey85", "grey60")

8 Save for the later documents

Only the constants are saved - not the raw data. 01_prepare_data.Rmd reads the original file itself.

save(focus_sections, industry_labels, industry_groups,
     division_codes, division_parent,
     country_groups, peer_countries, group_names,
     eu_comparators, eu15_comparators, nms_comparators, non_eu,
     ga_benchmark, periods,
     theme_pkp, grey_palette,
     file = "output/clean/00_setup.RData")

cat("00_setup complete\n")
## 00_setup complete
cat("  klems  :", nrow(klems), "rows x", ncol(klems), "columns |",
    min(klems$year), "-", max(klems$year), "\n")
##   klems  : 61128 rows x 236 columns | 1995 - 2021
cat("  annual :", nrow(annual), "rows x", ncol(annual), "columns |",
    min(annual$year), "-", max(annual$year), "\n")
##   annual : 495 rows x 35 columns | 2010 - 2025
cat("  sections :", paste(focus_sections, collapse = " "), "\n")
##   sections : C G H I J M
cat("  divisions:", length(division_codes), "\n")
##   divisions: 24
cat("  peers   :", length(peer_countries), "countries\n")
##   peers   : 20 countries
cat("  saved  :", round(file.size("output/clean/00_setup.RData")/1024, 1),
    "KB to output/clean/00_setup.RData\n")
##   saved  : 1.1 KB to output/clean/00_setup.RData