Introduction

The current series of vehicle registration plates in Kenya are on a white plate with black characters for the front and yellow plate and black characters in the rear and look quite similar to UK suffix style registrations. The format is XXX YYYX, where X denotes a letter and Y denotes a digit. The older series of number plates were black with white or silver characters. The rear plates in the older series of number plates were yellow and black characters. According to Kenya National Bureau of Statistics they are over 1,626,380 vehicles in Kenyan road as at 2011. Currently there are over 2.5 million vehicles running on our roads.

In this series of R Training I will be showcasing how one can generate all the serieses of number plates up to the current generation.

The task is to generate a sequence of the plate numbers in R. We start by removing all variables and objects stored in R.

rm(list=ls(all=TRUE)) 

Intall the library stringr. First check if the library is installed if it is not installed then install.

if("stringr" %in% rownames(installed.packages())==FALSE){
  install.packages("stringr")
}

Better still you can write your own function to check if the package is installed and install the same if it is not installed and load it there after. We will write a function called PkgInstaller

PkgInstaller <- function(package){
  if(!require(package,character.only = TRUE)){
    install.packages(package,dep = TRUE)
    if(!require(package, character.only = TRUE)) stop("package not found")
  }
};PkgInstaller("stringr")

The following package is not in any way limited or dependant on others but it will be necessary to accomplish the task at hand, simply put there are other packages you can use to accomplish the same task. I have used suppressMessages() to tell R not output any error or warning messages. I could have used library() function that works in a similar way to load the package.

suppressMessages(library(stringr))  # To load the library

Generations of Number Plates

In the next sections we subdivide the number plates into generations. Currently we have 4 generations of number plates. The first generation did not have a leter at the end while the rest all had a letter and still have one to date.

This was done to increase the number of possible number plates in a generation.

First Generation

The first vehicle was registered in Kenya slightly before 1920. Single letters were attributed to each of the 14 registration districts e.g. N=Kiambu, E=Kisumu, J=Kitale, B,H,T,W=Nairobi, A=Mombasa, C=Nakuru, D=Kericho, F=Eldoret, G=Nyeri, K=Muranga (Fort Hall), L=Kisii, Q=Machakos, S=Lamu, V=Isiolo, Y=Nanyuki. A serial number of 1-9999 followed, on white on black plates, save for commercial vehicles, which are thought to have used black on white.

In 1950 the K-prefix series was introduced and this changed to a three-letter numbering system, necessitated by the increasing number of vehicles being registered. It was introduced on a regional basis as follow, all plates began with K, followed by the regional code as illustrated below and a serial letter A-Z, not using letters I or O which upto date have been excluded.

  • Nairobi - KB (1950), KF (1955), KG (1959), KH (1961), KK (1965), KM (1968), KN (1970), KP (1972), KQ (1974), KR (1976) AND KV (1978)
  • Mombasa - KA (1950), KJ (1966), KT (1977)
  • Nakuru - KC (1950), KL (1967), KS (1977) Some KC and KL numbers were issued to Eldoret and Kitale.
  • Kisumu - KD (1950), KU (1977)
  • Nanyuki - KE
  • KBA was issued to Nyeri, the first Nairobi number being KBB. Nyeri then followed with KFE and KGT.
  • Kericho was issued with KDB then KDK which were used up to 1969.
  • Kisii was issued with KDE then shared KDK with Kericho.
  • Kakamega used KDL between 1962 and 1967. The numbering system was centralised in 1980 and after that date all Kenya numbers are in sequence. Between 1980 and 1984 the unused numbers from Nakuru (KS), Mombasa (KT) and Kisumu (KU) were issued, KW (1984) being the first number that was never used regionally.
suppressMessages(library(stringr))  # To load the library
entries <- LETTERS[seq( from = 1, to = 26 )][-6][-8][-13];entries
##  [1] "A" "B" "C" "D" "E" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S" "T"
## [18] "U" "V" "W" "X" "Y" "Z"
# First Generation Plate Numbers

# Step 1: Create a sereies of the 3 letter part

consoseries  <- vector()
for(i in 1:length(entries)){
  series <- paste0("K",rep(entries[i],length(entries)))
  consoseries <- c(consoseries,series)
}

letterSeries <- paste0(consoseries, rep(entries, length(entries)))

# Step 2: For each letter part replicate and code it 999 timee in sequence from 001 to 999

plateNumber <- vector()
for(i in 1:length(letterSeries)){
  numberSeries <- paste0(letterSeries[i], rep(str_pad(seq(1,999),3,pad = "0")))
  plateNumber <- c(plateNumber,numberSeries)
}

# Step 3: Not all the number plates generated above were used history has it these plates numbers were assigned
# Filter only the plate numbers that were used.

firstGenNums <- sort(c("KB","KF","KG","KH","KM","KN","KP","KQ","KR","KV","KA","KJ","KT","KC","KL","KS","KD","KU","KE","KC","KL","KBA","KBB","KFE","KGT","KDB","KDK","KDL"),decreasing = FALSE)
firstGen <- grep(paste(firstGenNums, collapse = '|'), plateNumber, value=TRUE)

# The first items in the sequence are.

head(firstGen)
## [1] "KAA001" "KAA002" "KAA003" "KAA004" "KAA005" "KAA006"
# The last items in the sequence are.

tail(firstGen)
## [1] "KVZ994" "KVZ995" "KVZ996" "KVZ997" "KVZ998" "KVZ999"

First generation firstGen vector above simply generates a sequence between AA and ZZ. History has it that at some point in 1980 the system was centralized and the plate numbers were issued in sequence.

The first generation had 528,471 number plates available for regestration of new cars coming in. As the popularity of vehicles increased this sequence was not enough to cater for the rising growth in the motor industry. Below is an illustration of how you can create the full series for the first generation. From KAA OO1 to KAA 999 then KAB 001 to KAB 999 and finally KZA 001 to KZA 999 then KZB 001 to KZB 999 then KZC 001 to KZC 999 and lastly KZZ 001 to KZZ 999.

rm(list=ls(all=TRUE))  # clear everything

# First we create serieses beginning with KA from A to Z each running 999 times.
# KAA, KAB, KBA, KBB through to KZA, KZB, KZZ ignoring KAF, KAI and KAO
consoseries <- vector()
entries <- LETTERS[seq( from = 1, to = 26 )][-6][-8][-13];entries
##  [1] "A" "B" "C" "D" "E" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S" "T"
## [18] "U" "V" "W" "X" "Y" "Z"
for(i in 1:length(entries)){
  series <- paste0("K",rep(entries[i],length(entries)))
  consoseries <- c(consoseries,series)
}

letterSeries <- paste0(consoseries, rep(entries, length(entries)))

# Generate the number sequence

plateNumber <- vector()
for(i in 1:length(letterSeries)){
  numberSeries <- paste0(letterSeries[i], " ",rep(str_pad(seq(1,999),3,pad = "0")))
  plateNumber <- c(plateNumber,numberSeries)
}
# Finally assign the vector to an new variable

firstGen <- plateNumber

The first series runs from 001 and runs to 999

firstGen[995:999]
## [1] "KAA 995" "KAA 996" "KAA 997" "KAA 998" "KAA 999"

Then the second series runs starts again after hitting 999 mark and starts again and runs from 001 to 999

firstGen[1000:1005]
## [1] "KAB 001" "KAB 002" "KAB 003" "KAB 004" "KAB 005" "KAB 006"

The first generation had a total of 528,471 number plates. The last registration numbers under this generation were.

firstGen[528465:528471]
## [1] "KZZ 993" "KZZ 994" "KZZ 995" "KZZ 996" "KZZ 997" "KZZ 998" "KZZ 999"

It is however not very clear how many of these number plates in the first generation were used after centralization of the system. Poor record keeping and lack of computers was a major drawback.

Second Generation

I988 was a special year……….. I was born. One year after my brother was born. After the registration of vehicle KZZ 999, the second generation was started in 1989. The second generation added a letter at the end of first generation sequence and each series the last letter also known as the stroke ran between A and Z excluding F, I and O. The advantage being that each third letter of the number provided for 23,976 registrations instead of the previous 999. Hence for the series to be finished about 575,424 vehicle will be registered.

rm(list=ls(all=TRUE))  # clear everything
# First we create a series of the letters part and put them into an empty vector.
# The series start from AA running with strokes A to Z excluding F, I and O
consoseries <- vector()
entries <- LETTERS[seq( from = 1, to = 26 )][-6][-8][-13];entries
##  [1] "A" "B" "C" "D" "E" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S" "T"
## [18] "U" "V" "W" "X" "Y" "Z"
strokesEntries <- LETTERS[seq( from = 1, to = 26 )][-9][-14];strokesEntries
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S"
## [18] "T" "U" "V" "W" "X" "Y" "Z"
for(i in 1:length(entries)){
  series <- paste0("KA",rep(entries[i],each = 999)," ",rep(str_pad(seq(1,999),3,pad = "0"),length(strokesEntries)))
  consoseries <- c(consoseries,series)
}

# The second part creates a sequence of strokes equivalent to the length of series above.
# For each series the stroke runs once there are 23 serieses in the generation.

strokes <- vector()
for(i in 1:length(strokesEntries)){
  series <- rep(strokesEntries[i],999)
  strokes <- c(strokes,series)
}

# At this point we replicate the strokes 23 time to fit in the number of serieses.
# A stroke is each letter in the entries A to Z excluding F, I, O.

strokes <- rep(strokes,length(entries))

# The final part joins all the serieses with the the strokes
secondGen <- paste0(consoseries,strokes)

Note that the the F letter is reserved because of the KAF Armed Forces vehicles. However on the stroke ie last letter it is included. The serieses in the second generation had strokes. The A series ran from 1 to 999 with stroke A as shown below.

secondGen[995:999]
## [1] "KAA 995A" "KAA 996A" "KAA 997A" "KAA 998A" "KAA 999A"

The series then ran through stroke B as shown below.

secondGen[1000:1005]
## [1] "KAA 001B" "KAA 002B" "KAA 003B" "KAA 004B" "KAA 005B" "KAA 006B"

It is important to check whether the series starts after running to the last plate number is a series to the last stoke to ensure all entries are taken into account. Below we check at what point the AB series starts.

secondGen[23976:23981]
## [1] "KAA 999Z" "KAB 001A" "KAB 002A" "KAB 003A" "KAB 004A" "KAB 005A"

The last plate numbes under this generation were:

r secondGen[551442:551448]

## [1] "KAZ 993Z" "KAZ 994Z" "KAZ 995Z" "KAZ 996Z" "KAZ 997Z" "KAZ 998Z" ## [7] "KAZ 999Z" This generation had more plate numbers as compared to the first generation. Total number plates 551,448 in total. The second generation saw the number of vehicles increase by 22,977 perharps an increase 551,448 in the long run. This is just silly nothing to talk about home probably a story over a bottle of beer.

Third Generation

After the registration of vehicle KAZ 999Z, the third generation was started in 2007 as KBA 001A. The series will run from KBA 001A to KBZ. In 2014, the government announced a revamp of the registration plates to a new look, featuring electronic chips. The third generation saw the return of letter F to the 3 series letters. This was big milestone to the car registrar if you ask them.

rm(list=ls(all=TRUE))  # clear everything
# First we create a series of the letters part and put them into an empty vector.
# The series start from AA running with strokes A to Z excluding F, I and O
consoseries <- vector()
entries <- LETTERS[seq( from = 1, to = 26 )][-9][-14];entries
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S"
## [18] "T" "U" "V" "W" "X" "Y" "Z"
strokesEntries <- LETTERS[seq( from = 1, to = 26 )][-9][-14];strokesEntries
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S"
## [18] "T" "U" "V" "W" "X" "Y" "Z"
for(i in 1:length(entries)){
  series <- paste0("KB",rep(entries[i],each = 999)," ",rep(str_pad(seq(1,999),3,pad = "0"),length(strokesEntries)))
  consoseries <- c(consoseries,series)
}

# The second part creates a sequence of strokes equivalent to the length of series above.
# For each series the stroke runs once there are 23 serieses in the generation.

strokes <- vector()
for(i in 1:length(strokesEntries)){
  series <- rep(strokesEntries[i],999)
  strokes <- c(strokes,series)
}

# At this point we replicate the strokes 23 time to fit in the number of serieses.
# A stroke is each letter in the entries A to Z excluding F, I, O.

strokes <- rep(strokes,length(entries))

# The final part joins all the serieses with the the strokes
thirdGen <- paste0(consoseries,strokes)

The third registration numbers plates started with these sequence of number plates:

r thirdGen[1:5]

## [1] "KBA 001A" "KBA 002A" "KBA 003A" "KBA 004A" "KBA 005A" While the last registration numbers under this generation were:

r thirdGen[575420:575424]

## [1] "KBZ 995Z" "KBZ 996Z" "KBZ 997Z" "KBZ 998Z" "KBZ 999Z"

Fourth Generation

2014 was another special year the hard work I had put in school, work place and working smart in life finally paid off I bought my first car which was registered under the fourth generation of number plates. After the registration of vehicle KBZ 999Z, the fourth generation was started in 2014 as KCA 001A. The series will run from KCA 001A to KCZ 999Z. This was the current series as at publication of this work in 2018. The series was at KCQ.

rm(list=ls(all=TRUE))  # clear everything
# First we create a series of the letters part and put them into an empty vector.
# The series start from AA running with strokes A to Z excluding F, I and O
consoseries <- vector()
entries <- LETTERS[seq( from = 1, to = 26 )][-9][-14];entries
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S"
## [18] "T" "U" "V" "W" "X" "Y" "Z"
strokesEntries <- LETTERS[seq( from = 1, to = 26 )][-9][-14];strokesEntries
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "J" "K" "L" "M" "N" "P" "Q" "R" "S"
## [18] "T" "U" "V" "W" "X" "Y" "Z"
for(i in 1:length(entries)){
  series <- paste0("KC",rep(entries[i],each = 999)," ",rep(str_pad(seq(1,999),3,pad = "0"),length(strokesEntries)))
  consoseries <- c(consoseries,series)
}

# The second part creates a sequence of strokes equivalent to the length of series above.
# For each series the stroke runs once there are 23 serieses in the generation.

strokes <- vector()
for(i in 1:length(strokesEntries)){
  series <- rep(strokesEntries[i],999)
  strokes <- c(strokes,series)
}

# At this point we replicate the strokes 23 time to fit in the number of serieses.
# A stroke is each letter in the entries A to Z excluding F, I, O.

strokes <- rep(strokes,length(entries))

# The final part joins all the serieses with the the strokes
fourthGen <- paste0(consoseries,strokes)

The fourth generation started with a sequence of the following number plates:

r fourthGen[1:5]

## [1] "KCA 001A" "KCA 002A" "KCA 003A" "KCA 004A" "KCA 005A" As at the time of this publication registration numbers were at KCP.

fourthGen[298701:298705]
## [1] "KCN 999L" "KCN 001M" "KCN 002M" "KCN 003M" "KCN 004M"

If you ever get a job with National Transport and Safety Authority or any body that deals with vehicle registration and population this is a stepping stone to build on the analytics. Special Number plates for Kenya Defence Forces, Diplomats, County Governments, Parastatals, Motorcycles, Heavy Machinery, NGOs, Dealers, United Nations etc have been omitted in this work. Please remember to include them as you advance this piece of work. God Bless you.

                                                       THE END