Financial situation of municipalities in North Rhine-Westphalia, Germany

The financial situation of municipalities is often dire. North Rhine-Westphalia, Germany’s biggest state, is generally thought to be in the worst financial situation. High per capita debt is often accompanied by a high share of short-term debt which strongly exposes the municipalitiy to interest rate risk.

Using data from 382 municipalities, I will start with a graphical explanatory analysis.

The data can be obtained from here. For creating the map of per capita debt, I borrowed heavily form Mark Heckmann.

The R code can be seen after the plots. It still needs some cleaning up. Let me know if you have any questions or if you have suggestions for further analysis.

require(ggplot2)
require(ggmap)
require(mapproj)
library(sp)
library(RColorBrewer)
library(scales)

setwd("/Users/christophpfeiffer/Downloads/Kommunalfinanzen")
Ergebnis09<-read.table("Ergebnis2009.txt",sep=";",encoding='latin1')
Ergebnis10<-read.table("Ergebnis2010.txt",sep=";",encoding='latin1')
Bilanz<-read.table("Bilanz.txt",sep=";",encoding='latin1')
names(Ergebnis09)<-c("Gemeindeschl","Verwaltungsform","Name","Produktgruppe","Text.Produktgruppe","Konto","Konto.Text","Wert")
names(Ergebnis10)<-c("Gemeindeschl","Verwaltungsform","Name","Produktgruppe","Text.Produktgruppe","Konto","Konto.Text","Wert")
names(Bilanz)<-c("Amtlicher.GemS","Verwaltungsform","Name","Signatur","Signatur.text","Wert")
Ergebnis09[,9]<-NULL
Ergebnis10[,9]<-NULL
Bilanz[,7]<-NULL
names(Ergebnis09)==names(Ergebnis10)

#Join
Ergebnis09$Jahr<-2009
Ergebnis10$Jahr<-2010
Ergebnis<-rbind(Ergebnis09,Ergebnis10)

#Name as character / numeric
Ergebnis$Name<-as.character(Ergebnis$Name)
Ergebnis$Text.Produktgruppe<-as.character(Ergebnis$Text.Produktgruppe)
Ergebnis$Wert<-as.numeric(Ergebnis$Wert)
Ergebnis$Konto.Text<-as.character(Ergebnis$Konto.Text)
Bilanz$Name<-as.character(Bilanz$Name)
Bilanz$Signatur.text<-as.character(Bilanz$Signatur.text)

#Cut last empty space in character name
Ergebnis$Name<-substr(Ergebnis$Name,start=1,stop=nchar(Ergebnis$Name)-1)
Ergebnis$Text.Produktgruppe<-substr(Ergebnis$Text.Produktgruppe,start=1,stop=nchar(Ergebnis$Text.Produktgruppe)-1)
Ergebnis$Konto.Text<-substr(Ergebnis$Konto.Text,start=1,stop=nchar(Ergebnis$Konto.Text)-1)

Bilanz$Name<-substr(Bilanz$Name,start=1,stop=nchar(Bilanz$Name)-1)
Bilanz$Signatur.text<-substr(Bilanz$Signatur.text,start=1,stop=nchar(Bilanz$Signatur.text)-1)

#Look at variables
names(Ergebnis)
unique(Ergebnis$Name)
unique(Ergebnis$Verwaltungsform)
unique(Ergebnis$Text.Produktgruppe)
unique(Ergebnis$Konto.Text)

names(Bilanz)
unique(Bilanz$Verwaltungsform)
unique(Bilanz$Name)->name
unique(Bilanz$Signatur.text)

a<-list()
b<-which(Bilanz$Signatur.text=="Verbindlichkeiten mit einer Restlaufzeit von bis zu 1 Jahr")
c<-which(Bilanz$Signatur.text=="Gesamtbetrag der Verbindlichkeiten am 31.12. des Haushaltsjahres")
for(i in 1:length(name)){
a[[i]]<-which(Bilanz$Name==name[i])
}

Schulden.r<-matrix(nrow=length(name),ncol=2)
for(i in 1:length(name)){
if(
length(which(is.element(b,a[[i]])))>0 &amp;
length(which(is.element(c,a[[i]])))>0)
{
Schulden.r[i,1]<-Bilanz[which(Bilanz$Name==name[i] &amp; Bilanz$Signatur.text=="Verbindlichkeiten mit einer Restlaufzeit von bis zu 1 Jahr"),]$Wert
Schulden.r[i,2]<- Bilanz[which(Bilanz$Name==name[i] &amp; Bilanz$Signatur.text=="Gesamtbetrag der Verbindlichkeiten am 31.12. des Haushaltsjahres"),]$Wert
}
else
Schulden.r[i,]<-NA
#Schulden.r[i]<-0
}

as.data.frame(Schulden.r)->Schulden.r
Schulden.r$Name<-name
names(Schulden.r)<-c("Verbindlichk.k","Verbindlichk.i","Name")
Schulden.r$Schulden.r<-Schulden.r$Verbindlichk.k/Schulden.r$Verbindlichk.i

Einwohnerzahl hinzufügen
Einw<-read.csv("Einwohner_Deutschland_Kreise.csv",header=TRUE,sep=";",encoding='latin1',colClasses=c("character","character","numeric","character","numeric","numeric","numeric"))
Einw$X<-NULL
names(Einw)[1]<-"Bundesland"
Einw.NRW<-Einw[Einw$Bundesland=="Nordrhein-Westfalen",]

Einw.NRW$Name <- gsub("Städte", "", Einw.NRW$Name)
order1<-c()

for(i in 1:nrow(Schulden.r)){
order1[i]<-pmatch(Schulden.r$Name[i],Einw.NRW$Name)
}

for(i in which(is.na(order1))){
order1[i]<-agrep(Schulden.r$Name[i],Einw.NRW$Name,max.distance=0.7)[1]
}

which(is.na(order1))

Schulden.r$Einwohner<-Einw.NRW$Insgesamt[order1]
names(Schulden.r)
Schulden.r$Schulden.pro.Einw<-Schulden.r$Verbindlichk.i/Schulden.r$Einwohner

Plot worst Schulden pro Einw
qplot(
x=reorder(Name,Schulden.pro.Einw),
y=Schulden.pro.Einw,
data=top.x, col=I("blue")
)+coord_flip()+theme_minimal()

P1<-qplot(x=reorder(Name,Schulden.r),y=Schulden.r, data=top.x, col=Einwohner,size=Schulden.pro.Einw,alpha=I(0.7))
P1<-P1+theme_minimal()+ theme(legend.position="none")+opts(axis.text.x=theme_text(angle=0))+coord_flip()
P1+ylab("Stadt")+xlab("Verhältnis kurzfristige Schulden zu Schulden insg.")

##4 Feld Graphik
head(Schulden.r[order(Schulden.r$Schulden.pro.Einw,decreasing=T),],22)->top.x
which(is.na(top.x))
P2<-qplot(x=Schulden.r,y=Schulden.pro.Einw, data=top.x,
label=Name, col=Schulden.pro.Einw,size=Einwohner,
alpha=I(0.5),xlim=c(0.2,0.9),ylim=c(3000,8000))
P2<-P2+theme_minimal()+ theme(legend.position="none")
P2<-P2+scale_area(range=c(5,30),guide="none")+geom_text(size=5,hjust=0.3,vjust=0.3,color="black")
P2+ylab("Verbindlichenkeiten pro Einwohner")+xlab("Fremdkapitalstruktur")+geom_smooth(method="lm",se=F,col=I("black"))+
labs(title="Finanzsituation der 22 Kommunen in NRW mit der höchsten pro Kopf Verschuldung")+
scale_colour_gradient2(low="blue", mid="blue",high="red",guide="none")


qplot(y=Schulden.pro.Einw,x=Schulden.r,data=Schulden.r[-which(Schulden.r$Schulden.r<0),],
geom="point",alpha=I(0.5),size=Einwohner)+theme_minimal()+geom_smooth()+ theme(legend.position="none")
Visualisieurng
p1<-qplot(Schulden.r,
data=Schulden.r[-Schulden.r$Schulden.r<0|is.na(Schulden.r$Schulden.r),],
geom="density",fill=I("blue"),alpha=I(0.7),color=I("white"))
p1+theme_minimal()+labs(title="Verhältnis kurzfristige zu langfriste Schulden in NRW")+xlab("Schuldenratio")

con <- url("http://gadm.org/data/rda/DEU_adm3.RData")
print(load(con))
close(con)

# plot Germany with random colors
col = rainbow(length(levels(gadm$NAME_3)))
spplot(gadm, "NAME_3", col.regions=col, main="German Regions",
colorkey = FALSE, lwd=.4, col="white")

#Only NRW
gadm.nrw<-gadm[gadm$NAME_1=="Nordrhein-Westfalen",]
spplot(gadm.nrw, "NAME_3", col.regions=col, main="German Regions NRW",
colorkey = FALSE, lwd=.4, col="white")

gadm_names <- iconv(gadm.nrw$NAME_3, "ISO_8859-2", "UTF-8")

#Match kurzfristiger Verschuldungsratio
Schulden.r[-c(376:382),]->Schulden.r

gadm_names_n <- gsub("Städte", "", gadm_names)
Schulden.r$Name <- gsub("Kreis", "", Schulden.r$Name)
Schulden.r$Name <- gsub("Kreisverwaltung", "", Schulden.r$Name)

gadm_names_n[1]<-"Köln"

order<-c()
for(i in 1:length(gadm_names_n)){
order[i]<-pmatch(gadm_names_n[i], Schulden.r$Name)
}

for(i in which(is.na(order))){
order[i]<-agrep(gadm_names_n[i], Schulden.r$Name,max.distance=0.3)[1]
}

which(is.na(order))

as.data.frame(gadm_names_n)->gadm_n
gadm_n$Schulden.pro.Einwohner<-Schulden.r$Schulden.pro.Einw[order]

col_no <- as.factor(as.numeric(cut(gadm_n$Schulden.pro.Einwohner,c(0,500,1000,2000,3000,4000,5000,6000,8000))))
levels(col_no) <- c("<500EUR","500-1000EUR","1000-2000EUR","2000-3000EUR","3000-4000EUR","4000-5000EUR","5000-6000EUR",">6000EUR")
gadm_n[which(is.na(col_no)),]
gadm.nrw$col_no <- col_no
myPalette<-brewer.pal(length(levels(col_no)),"Reds")
spplot(gadm.nrw, "col_no", col=grey(.9), col.regions=myPalette,main="Pro Kopf Verschuldung NRW")

Leave a Reply

Your email address will not be published. Required fields are marked *