Today we will be looking at homicide html data in Baltimore from the Baltimore Sun's very own Sun Data Desk. I will demonstrate the power of regular expressions in extracting data, especially from structured data sets, like html through R.
Text, Lots of Text
| Fig. 1: Homicide html text |
Let us begin with some examples in R to demonstrate how we can use regular expressions to clean and analyze the raw data.
1. Causes of each Homicide
With all this data about homicides in Baltimore since 2007, it would useful to start with the causes of each homicide, as exploratory analysis. So I will now create a table with counts for each cause.
The information for each homicide case is on its own line. I read in the data using the readLines function into a data.frame d, and use head of d to print the first six cases.
| Fig. 2: Reading in the Data using readLines |
| Fig. 3: regexec Function |
The second member of all represents the match length of the string from the starting point. It is 24 for the first element and 8 for the second match, and it is logical that the second is shorter because it was inside the larger matched string segment (just the actual cause, and not the Cause: from <dd> to </dd>.) Confusing? (Take a look at Figure 4.) This is verified below with the regmatches function.
| Fig. 4: regmatches Function |
Now this match list can be used to count the number of each type of homicide. However, we just want to extract the strings in the second set of each member in the match list, which contain just the actual cause (blunt force, shooting, etc.), and not the entire matched string with html tags. So we use sapply to slice only the second list member (x[2]) into the causes vector.
| Fig. 5: sapply Function |
Here we have the causes character vector with all the strings of the causes of homicides. We could now do table(causes), but there are some actual causes which were input capitalized so we need to include them as the same cause even if they are spelled differently, using the tolower function.
| Fig. 6: tolower Function and Table of Causes |
2. Age Distribution of Victims
Next, we can analyze the age distribution of victims to see how old the victims were at the time of homicide. After reading in the data from analyzing causes in the above example, we look at age, specifically the number before "years old", as shown below (Figure 7) for the first line.
| Fig. 7: First Line, Age 17 years old |
| Fig. 8: Indexes from the regexec Function for age |
The output of years first gives the start position of the match (160) then the corresponding match length (17), followed by the segments in parenthesis. So the digits match begin at 160, and continue for 2 characters, then the spellings of the years follows at position 163 for 5 units.
These positions are matched with the data with regmatches to return the strings shown in Figure 9.
| Fig. 9: String Matches with the regmatches Function |
| Fig. 10: Using sapply function to extract desired string |
Now we can create a histogram to plot the age distributions from the age vector with:
| Fig. 11: Creating a Histogram |
| Fig. 11: Age Distribution of Homicide Victims |
Thanks for reading,
Wayne
