naijR 0.5.0

A new version of this R package has been released on CRAN, the Comprehensive R Archive Network. It introduces a number of updates that will be described in somewhat detail in this blog post. For a synopsis, read the release notes.

New methods

Methods for some common generic R functions were included in the update. Some of these include c(), [, [[, na.exclude, to mention a few. This confers consistent behaviour to some of the **naijR** objects. For example, when concatenating 2 objects that represent the Nigerian States, we have the following:

s1 <- states("Imo")
s2 <- states(c("Abia", "Anambra"))
s3 <- c(s1, s2)
## States
## ------ 
## * Imo
## * Abia
## * Anambra 

Similarly, when indexing, the output formatting is retained:

## States
## ------ 
## * Imo 

Other methods added are as follows:

  • head.regions
  • tail.regions
  • print.regions
  • na.exclude.regions
  • na.omit.regions

Mobile numbers

The function fix_mobile can now repair phone numbers where zeros (0) are mistakenly replaced with the letter O (whether upper or lower case). As an example:

nums <- c("8034510441", "070304", "09O14358956")

# nums[3] has a letter 'O' in it and is fixed by the function
[1] "08034510441" NA            "09014358956"

Map legends

Changes were made to the arguments that control how legends are displayed in the maps, particularly choropleths. The way the argument legend.text works is similar to that of the barplot function (from the **graphics** package). Only when this argument is TRUE will the legend be plotted. Also, other arguments that were used for fine-tuning were deprecated – leg.x, leg.y, and leg.orient. Going forward, any low-level legend manipulations should be done with graphics::legend().

As an example, let us create a 2-column data frame with hypothetical data on the

# Create a factor

x <- states() |>
  length() |>
  rnorm(100, 10) |>
  round() |>
  sample() |>
    breaks = c(80, 89, 99, 109, 119, 129), 
    labels = c("80-89", "90-99", "100-109", "110-119", "120+"),
    include.lowest = TRUE

# Make a 2-column data frame and take a look at it
df <- data.frame(state = states(), x)

This gives the following output:

##       state       x
## 1      Abia   90-99
## 2   Adamawa   90-99
## 3 Akwa Ibom    120+
## 4   Anambra 100-109
## 5    Bauchi   90-99
## 6   Bayelsa   90-99

Now, we will use this data frame to create a choropleth map. One of the improvements in this version is that the function map_ng(), when given a two-column data frame will inspect each column, and if one column has valid States or LGAs and the other is a factor, it will automatically create the choropleth visualization. So using our data frame df,

map_ng(data = df)

With the new control given in the current version, we can do away with the legend.

# note partial matching with argument 'legend.text'
map_ng(data = df, legend = FALSE)

Due to the shape of the map, the best place to place any legend is in the bottom right corner. However, if the user wants to place it elsewhere, we can now use the Base R plotting constructs to do fine-grained touch-ups. This, of course, is for users who are more comfortable coding in R. As an example,

# Create objects containing the factor levels and then the colours
# map_ng() uses RColorBrewer internally, so we are using this
# to manually define the colours for the legend itself
categories <- levels(df$x)
colors <- RColorBrewer::brewer.pal(length(categories), "Greys")

# The legend's data, colours, orientation, justification, size and spacing are defined
res <- map_ng(data = df, legend = FALSE)
legend("top", categories, fill = colors, horiz = TRUE, xjust = .8, cex = .55, x.intersp = .5)

So much more can be done with this; details can be found in the documentation via ?legend.


The new version of the package can be installed from CRAN with the following code:


Feedback on the package is welcome – feel free to post a GitHub issue at

Happy coding!

Leave a comment

Filed under Uncategorized, data science

naijR 0.4.4

This is to announce the release of a new version of naijR, a package designed to make it easier to work with data related to Nigeria. In this update, a bug related to the fix_mobile function was fixed. In older versions, whenever a vector made up of only missing values (NA) was passed to it, it failed with the following error:

# The first number is fixed and the missing value untouched
> raw.numbers <- c("8031111111", NA, "07061234567")
> fix_mobile(raw.numbers)
[1] "08031111111" NA            "07061234567"

# But if all are missing values, it fails
> all.missing <- rep(NA, 6)
> fix_mobile(all.missing)
Error in fix_mobile(all.missing) : 
  Objects of type ‘logical’ are not supported

So if, for example, one was trying to clean up column(s) of a data frame that have phone numbers, whenever it encountered one that was empty, it failed. This has now been fixed in the current version: the function now returns such data unchanged.

> fix_mobile(all.missing)

For more information on the package, including how to install and use it, visit

Leave a comment

Filed under data science

A strange source of computer bugs

Today I looked at a tutorial on Visual Basic for Applications, the language that enables power users to program in Microsoft Office apps, notably Excel.

Now, in VBA, code comments can be defined with the single quote () character. Thus, this line of code would be a comment and ignored during program execution.

` This line of code is a comment

Somewhere down the line, I was reading the part where they described user-defined functions. Here’s the example:

Function Functionname(parameter-list) '
statement 1
statement 2
statement 3
statement n
End Function

Notice what I saw on the far-right end of line 1. This confused me a little because I remembered that the ' characters are for comments. So how could it possibly be used here?

After a little bit of searching without success, I returned to look at the example again, only to find that the character had disappeared! I nearly kicked myself: what I thought was a character was nothing but a speck on my screen. I lost precious minutes because I did not keep my screen clean enough.

Sometimes one can be so careless!

This reminded me of how the earliest computer bugs were discovered, for example, at Harvard University. It’s a fascinating story–you can read more about it here.

Leave a comment

Filed under Computers & Internet

RQDAassist 0.5.1

There’s a new release of RQDAassist, a package that was created to help RQDA users to overcome the difficulty of installing it on R version 4. The issues that led to this are explained in this post.

The need for today’s update is informed by the arrival of R 4.2.0 (“Vigorous Calisthenics”), which has presented some difficulty with the installation of key RQDA dependencies.


In R 4.2 the R Core Team has made 2 changes to the build system/toolset for Windows machines. They are:

  1. Migration of R builds (as well as package binaries) to the Universal C Runtime (UCRT).
  2. Changes in Rtools significantly affect how R and packages are built from source.

R and UCRT

As of version 4.2, R is to now switch from MSVCRT to UCRT. This is to enable native encoding of R builds on Windows to UTF-8. This is a welcome development as it makes internationalization easier, but as R Core has admitted, it also presents a few challenges. For a more detailed description of these changes, read this article from

Concerning RQDAassist, some of the archived binaries like RGtk2 required for RQDA are not compatible with R 4.2 since they were built with the old runtime. This is the first problem we encountered. The second problem is discussed in the next section.


In order to build R or any packages from source on Windows, we need Rtools, a collection of compilers, shells utilities, etc. For R 4.2, this toolchain was modified both in its content and behavior. With the failure to install RGtk2 binaries as mentioned earlier, we attempted to build RGtk2 from source (the function RQDAassist::install() provides an argument for both Installation approaches). This also proved to be problematic with Rtools42, particularly when compiling the C code in RGtk2 with the GTK distribution.

Additional work will be required to overcome this challenge and there’s the possibility that an all-out upgrade of RGtk2 itself might be necessary. From the communication by the RGtk2 author, it seems the package was “accidentally” archived on CRAN, so part of the plan is to monitor the conversation before deciding on the next course of action.

The Why

One may wonder why I’m going through all this hassle. Why not just abandon RQDA and move on to some other software for qualitative data analysis? Well, I don’t know for sure – call it stubbornness if you will. But I have a team of analysts that have used RQDA working for me since 2019. I’ve invested a lot of time, energy, and money to get to this point where I can use this tool to provide the services for which we get paid.

But it’s also been a tremendous learning experience and I get emails from researchers who need some support to continue using RQDA. I am therefore motivated to do my little bit to help.

Changes to RQDAassist

The current change to RQDAassist is mainly to disable the installation of RQDA on R 4.2 and above. This is expected to be a temporary fix until such a time when we are able to migrate it to a current, upgraded R version.

Other changes include more efficient installation of binary RQDA dependencies like RGtk2 and cairoDevice, more informative messages for users, and a cleaner installation experience. Any attempt , however, to install it on R 4.2 or above will result in the following error message:

ERROR: this R is version 4.2.0, package 'RQDAassist' requires R < 4.2


To install RQDAassist, start your R session and use the following code

if (!requireNamespace("remotes")

To install RQDA, run


and for more information visit the help file with ?RQDAassist::install.

Leave a comment

Filed under Computers & Internet

My Network Sharing Apps

This is going to be very brief. The other day I watched a YouTube video by a well-known online business coach and was introduced to network (i.e. internet subscription data) sharing applications on the Google Play store.

Now I refrain from mentioning these apps here because I’m not trying to disparage them in any way. The purpose of this post is to inform those whom I shared this information with on what I’ve done with these apps. Well, I’ve deleted them.

I deleted them for the simple reason that they are not a good way for me to make money. The apps run in the background but I have to keep restarting them. That, for me, is a big problem because I simply don’t have that kind of time. I do mine the Pi cryptocurrency, but I have to tap on it only once a day and it runs well, so i can live with that. These apps, however, require my attention every 30 mins or so because they keep going off. It’s possible this is so because the roving IP of my mobile provider – it may be more stable with WiFi connections but I’ve not tried it out yet.

Some online “businesses” seem more like slavery

The payout is definitely not worth my time – i can’t earn up to a dollar per day on any of those apps. The time required to keep restarting and monitoring them to earn next to nothing is a pure waste of time, in my opinion. Online surveys are better; at least they teach you a thing or two.

So, guys (you know yourselves), I’m out. You’re welcome to continue and see what the future holds with the apps. As for me, I don’t have the time to spare.

Leave a comment

Filed under Rants