Benford's Law in R
r
Solution
In order to ensure that all digits are represented in `first_digit_counts`, you can convert `first.digit` to a factor, explicitly setting the levels so they include all digits from 1 to 9:
first_digit = c(1, 1, 3, 5, 5, 5, 7, 7, 7, 7, 9)
first_digit_factor = factor(first_digit, levels=1:9) # Explicitly set the levels
That makes your `table` calls perform as expected:
> table(first_digit)
first_digit
1 3 5 7 9
2 1 3 4 1
> table(first_digit_factor)
first_digit_factor
1 2 3 4 5 6 7 8 9
2 0 1 0 3 0 4 0 1
> as.vector(table(first_digit_factor))
[1] 2 0 1 0 3 0 4 0 1
Problem
I'm trying to implement Benford's Law in R. So far, everything works accordingly, except that if there are some first-digits with 0 occurrences, an exception is thrown: ``` Error in data.frame(digit = 1:9, actual.count = first_digit_counts, actual.fraction = first_digit_counts/nrow(fraudDetection), : arguments imply differing number of rows: 9, 5 ``` This is because for my current data set, there are only first digits starting with 1, 2, 7, 8 and 9. How can I make it such that 3, 4, 5, 6 will have a count of 0 instead of not appearing at all in the table? Current Data Set: This is the part that is causing the exception to be thrown: ``` first_digit_counts <- as.vector(table(fraudDetection$first.digit)) ``` The current code in which this code fits in is as follows: ``` # load the required packages require(reshape) require(stringr) require(plyr) require(ggplot2) require(scales) # load in data from CSV file fraudDetection <- read.csv("Fraud Case in Arizona 1993.csv") names(fraudDetection) # take only the columns containing the counts and manipulate the data into a "long" format with only one value per row # let's try to compare the amount of the fraudulent transactions against the Benford's Law fraudDetection <- melt(fraudDetection["Amount"]) # add columns containing the first and last digits, extracted using regular expressions fraudDetection <- ddply(fraudDetection, .(variable), transform, first.digit = str_extract(value, "[123456789]"), last.digit = str_extract(value, "[[:digit:]]$")) # compare counts of each actual first digit against the counts predicted by Benford’s Law first_digit_counts <- as.vector(table(fraudDetection$first.digit)) first_digit_actual_vs_expected <- data.frame( digit = 1:9, actual.count = first_digit_counts, actual.fraction = first_digit_counts / nrow(fraudDetection), benford.fraction = log10(1 + 1 / (1:9)) ) ```