我正在尝试编写一些将采用数据框并绘制每个数字列的内容,其中包含非正态分布的简单绘图和正常分布的控制图:
library(plyr)
library(qcc)
library(ggplot2)
#generate data frame
data <- data.frame(seq_len(10),LETTERS[seq_len(10)],rnorm(10,5,3),rep(1,10),rep(2,10),rnorm(10,3,1),runif(10))
##checks heterogeneity
has_range <- function(data) { if(all( abs(data - mean(data)) == 0)) FALSE else TRUE}
##test for normality
normtest <- function(data) {if(has_range(data) == FALSE) FALSE else {
if(shapiro.test(data)$p.value < 0.05) FALSE else TRUE}}
##Control charts for Normal data, simple plots otherwise
drawplot<-function(data, ref=NULL) {
Sys.sleep(.1)
print(names(data))
if(normtest(data) == FALSE) {
plot(x=ref, y=data, ylab=names(data))
} else {
qcc(data,type="xbar.one", labels=ref, ylab=names(data))
}
}
## Apply drawplot to all numeric columns in data frame
colwise(drawplot, is.numeric, ref=data[[2]])(data)
问题是每个apply系列函数似乎都删除了列名,我不能使用列名来标记这些图:
print(names(data))
给出NULL结果。
此外还出现了一个看似无关的错误:
Error: length(rows) == 1 is not TRUE
答案 0 :(得分:2)
您需要创建一个使用名称的函数,否则函数中将无法访问这些名称。
你无法将x = NULL
传递给plot
,所以我重写了一些你的功能
(qcc
正在为x
的原子向量大惊小怪)
像
这样的东西drawplot<-function(n, data, ref=NULL) {
Sys.sleep(.1)
print(n)
if(normtest(data[[n]]) == FALSE) {
if(is.null(ref)){ref <- seq_along(data[[n]])}
plot(x=ref, y=data[[n]], ylab=n)
} else {
qcc(data[,n, drop=FALSE], type="xbar.one", labels=ref,ylab = n)
}
}
lapply(names(Filter(is.numeric,dd)), drawplot, data = dd)
请注意,此函数也适用于位置索引(但标签不会那么漂亮)