[英]Properly calling variable name when creating multiple Benford plots
我正在為我的數據集中的所有數字變量創建Benford圖。 https://en.wikipedia.org/wiki/Benford%27s_law
運行單個變量
#install.packages("benford.analysis")
library(benford.analysis)
plot(benford(iris$Sepal.Length))
看起來很棒。 傳說中的“數據集:虹膜$ Sepal.Length”,完美無缺!
使用apply
運行4個變量,
apply(iris[1:4], 2, function(x) plot(benford(x)))
創建四個圖,但是,每個圖的圖例都說“Dataset:x”
我試圖使用for循環,
for (i in colnames(iris[1:4])){
plot(benford(iris[[i]]))
}
這創建了四個圖,但現在傳說說“數據集:虹膜[[i]]”。 我希望每張圖表上的變量名稱。
我嘗試了一個不同的循環,希望獲得帶有評估解析字符串的標題,如“iris $ Sepal.Length”:
for (i in colnames(iris[1:4])){
plot(benford(eval(parse(text=paste0("iris$", i)))))
}
但現在傳說中的“數據集:eval(解析(text = paste0(”iris $“,i)))”。
AND ,現在我遇到了臭名昭着的eval(parse(text=paste0(
(例如: 如何通過“paste0”返回“eval”結果?並且R:eval(parse(...))通常不是最理想的 )
我想要標簽,如“Dataset:iris $ Sepal.Length”或“Dataset:Sepal.Length”。 如何在圖例中創建具有有意義變量名稱的多個圖?
這是因為benford
函數中的第一行=:
benford <- function(data, number.of.digits = 2, sign = "positive", discrete=TRUE, round=3){
data.name <- as.character(deparse(substitute(data)))
資料來源: https : //github.com/cran/benford.analysis/blob/master/R/functions-new.R
然后使用data.name
命名您的圖形。 遺憾的是,傳遞給函數的變量名稱或表達式將被deparse(substitute())
調用捕獲,並將用作圖形的名稱。
一個短期解決方案是復制和重寫功能:
#install.packages("benford.analysis")
library(benford.analysis)
#install.packages("data.table")
library(data.table) # needed for function
# load hidden functions into namespace - needed for function
r <- unclass(lsf.str(envir = asNamespace("benford.analysis"), all = T))
for(name in r) eval(parse(text=paste0(name, '<-benford.analysis:::', name)))
benford_rev <- function{} # see below
for (i in colnames(iris[1:4])){
plot(benford_rev(iris[[i]], data.name = i))
}
這有以下負面影響:
所以希望有人可以提出更好的方法!
benford_rev <- function(data, number.of.digits = 2, sign = "positive", discrete=TRUE, round=3, data.name = as.character(deparse(substitute(data)))){ # changed
# removed line
benford.digits <- generate.benford.digits(number.of.digits)
benford.dist <- generate.benford.distribution(benford.digits)
empirical.distribution <- generate.empirical.distribution(data, number.of.digits,sign, second.order = FALSE, benford.digits)
n <- length(empirical.distribution$data)
second.order <- generate.empirical.distribution(data, number.of.digits,sign, second.order = TRUE, benford.digits, discrete = discrete, round = round)
n.second.order <- length(second.order$data)
benford.dist.freq <- benford.dist*n
## calculating useful summaries and differences
difference <- empirical.distribution$dist.freq - benford.dist.freq
squared.diff <- ((empirical.distribution$dist.freq - benford.dist.freq)^2)/benford.dist.freq
absolute.diff <- abs(empirical.distribution$dist.freq - benford.dist.freq)
### chi-squared test
chisq.bfd <- chisq.test.bfd(squared.diff, data.name)
### MAD
mean.abs.dev <- sum(abs(empirical.distribution$dist - benford.dist)/(length(benford.dist)))
if (number.of.digits > 3) {
MAD.conformity <- NA
} else {
digits.used <- c("First Digit", "First-Two Digits", "First-Three Digits")[number.of.digits]
MAD.conformity <- MAD.conformity(MAD = mean.abs.dev, digits.used)$conformity
}
### Summation
summation <- generate.summation(benford.digits,empirical.distribution$data, empirical.distribution$data.digits)
abs.excess.summation <- abs(summation - mean(summation))
### Mantissa
mantissa <- extract.mantissa(empirical.distribution$data)
mean.mantissa <- mean(mantissa)
var.mantissa <- var(mantissa)
ek.mantissa <- excess.kurtosis(mantissa)
sk.mantissa <- skewness(mantissa)
### Mantissa Arc Test
mat.bfd <- mantissa.arc.test(mantissa, data.name)
### Distortion Factor
distortion.factor <- DF(empirical.distribution$data)
## recovering the lines of the numbers
if (sign == "positive") lines <- which(data > 0 & !is.na(data))
if (sign == "negative") lines <- which(data < 0 & !is.na(data))
if (sign == "both") lines <- which(data != 0 & !is.na(data))
#lines <- which(data %in% empirical.distribution$data)
## output
output <- list(info = list(data.name = data.name,
n = n,
n.second.order = n.second.order,
number.of.digits = number.of.digits),
data = data.table(lines.used = lines,
data.used = empirical.distribution$data,
data.mantissa = mantissa,
data.digits = empirical.distribution$data.digits),
s.o.data = data.table(second.order = second.order$data,
data.second.order.digits = second.order$data.digits),
bfd = data.table(digits = benford.digits,
data.dist = empirical.distribution$dist,
data.second.order.dist = second.order$dist,
benford.dist = benford.dist,
data.second.order.dist.freq = second.order$dist.freq,
data.dist.freq = empirical.distribution$dist.freq,
benford.dist.freq = benford.dist.freq,
benford.so.dist.freq = benford.dist*n.second.order,
data.summation = summation,
abs.excess.summation = abs.excess.summation,
difference = difference,
squared.diff = squared.diff,
absolute.diff = absolute.diff),
mantissa = data.table(statistic = c("Mean Mantissa",
"Var Mantissa",
"Ex. Kurtosis Mantissa",
"Skewness Mantissa"),
values = c(mean.mantissa = mean.mantissa,
var.mantissa = var.mantissa,
ek.mantissa = ek.mantissa,
sk.mantissa = sk.mantissa)),
MAD = mean.abs.dev,
MAD.conformity = MAD.conformity,
distortion.factor = distortion.factor,
stats = list(chisq = chisq.bfd,
mantissa.arc.test = mat.bfd)
)
class(output) <- "Benford"
return(output)
}
我剛剛更新了包(GitHub版本)以允許用戶提供的名稱。
現在該函數有一個名為data.name
的新參數,您可以在其中提供帶有數據名稱的字符向量並覆蓋默認值。 因此,對於您的示例,您只需運行以下代碼即可。
首先安裝GitHub版本(我將盡快將此版本提交給CRAN)。
devtools::install_github("carloscinelli/benford.analysis") # install new version
現在,您可以在for循環中提供數據的名稱:
library(benford.analysis)
for (i in colnames(iris[1:4])){
plot(benford(iris[[i]], data.name = i))
}
並且所有圖表都將根據您的意願正確命名(如下)。
由reprex包創建於2019-08-10(v0.2.1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.