2013-07-10 4 views
2

Je suis en train de mettre en œuvre la loi de Benford R. Jusqu'à présent, tout fonctionne en conséquence, sauf que s'il y a des premiers-chiffres avec 0 occurrences, une exception est levée:loi de Benford dans R

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 

C'est parce que pour mon ensemble de données actuel, il n'y a que les premiers chiffres commençant par 1, 2, 7, 8 et 9. Comment faire en sorte que 3, 4, 5, 6 aura un compte de 0 au lieu de ne pas apparaître du tout dans la table?

Current Data Set:

Data Set

Ceci est la partie qui est à l'origine l'exception à jeter:

first_digit_counts <- as.vector(table(fraudDetection$first.digit)) 

Le code actuel dans lequel ce code correspond à est aussi suit:

# 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)) 
) 
+4

Il est difficile sans un exemple facilement reproductible. Je pense que la réponse pourrait être de convertir 'first.digit' en un facteur avec les niveaux 0-9. – Marius

+0

Actuellement, les niveaux sont en tant que tels, par conséquent, il manque plusieurs chiffres, ce qui entraîne une discordance de lignes .. Penser comment effectuer l'affacturage si la sortie originale manquait déjà quelques chiffres .. Hmm .. 'fraudeDétection $ first .digit [1] 1 2 8 7 8 9 9 8 8 9 7 8 9 9 8 9 9 8 9 8 9 8 7 Niveaux: 1 2 7 8 9' – Outrigger

Répondre

6

Afin de faire en sorte que tous les chiffres sont représentés dans first_digit_counts, vous pouvez convertir first.digit à un facteur, définissant explicitement les niveaux afin qu'ils comprennent tous les chiffres de 1 à 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 

Cela rend vos table appels effectuent comme prévu:

> 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 
2

Une fonction de ceci est disponible à partir du paquet rattle

library(rattle) 
dummy <- rnorm(100) 
calcInitialDigitDistr(dummy, split = "none") 
0

Fonction utile d'une ligne

benford = function(x) barplot(table(as.numeric(substr(x,1,1)))) 

benford(ggplot2::diamonds$price) 

enter image description here

Questions connexes