我必须为多个变量制作一个直方图。我正在运行此代码,该代码按类别为我提供了多个变量的直方图。
hist_fun = function(x,y){
ggplot(df, aes(x, fill = y)) + geom_density(alpha = 0.2)
}
我在数据集上将此功能用作
lapply(df[sapply(df, is.numeric)], function(x) { hist_fun(x, df$class) })
我获得了所有图,但是我无法在x轴上获得标签。我尝试在通过x的xlab上使用,但没有任何作用。
hist_fun = function(x,y){
ggplot(df, aes(x, fill = y)) + geom_density(alpha = 0.2) + xlab(names(x))
}
还有什么更好的方法吗?
答案 0 :(得分:1)
我已经创建了一个示例data.frame:
# generate data.frame
df <- data.frame(num1 = rnorm(12),
num2 = rnorm(12)*2,
class = rep(c("class1", "class2", "class3"), 4))
您的函数(略作修改)会生成图,但是它将使用您在函数中定义的参数名称来标记您的审美观
# define function
hist_fun <- function(x,y){
ggplot(df, aes(x = x, fill = y)) + geom_density(alpha = 0.2)
}
# plot
library(ggplot2)
lapply(df[sapply(df, is.numeric)], hist_fun, df$class)
(请注意,我已经在lapply()
中删除了函数定义,因为您可以将参数传递给自定义函数。)
要开发正确使用ggplot2的功能,可以使用quasiquotation:
# define function
hist_fun <- function(x,y){
x <- enquo(x)
y <- enquo(y)
ggplot(df, aes(x = !!x, fill = !!y)) + geom_density(alpha = 0.2)
}
# plot
library(ggplot2)
lapply(df[sapply(df, is.numeric)], hist_fun, class)
这至少会理解您的class
参数,而不会引发关于使用class()
函数而不是变量的错误。但是我们仍然为x轴使用默认的x
标签。
aes_string()
一种解决方法是使用aes_string()
和names()
,它们将使用适当的标签:
# define function
hist_fun <- function(x,y){
ggplot(df, aes_string(x, fill = y)) + geom_density(alpha = 0.2)
}
# plot
library(ggplot2)
lapply(names(df[sapply(df, is.numeric)]), hist_fun, "class")
这是在没有申请家庭的情况下针对您的问题的稍微不同的解决方案:
# create a list to store plots
plots <- list()
# select only numerical variables
library(dplyr)
df_num <- select_if(df, is.numeric)
# store one plot for each numeric variable, using aes_string()
for (nm in names(df_num)) {
plots[[nm]] <- ggplot(df, aes_string(x = nm, fill = "class")) + geom_density(alpha = 0.2)
}
# print plots
plots
如果您的数值变量是相同类型的数据,我建议使用gather()
创建整洁的数据集,并使用构面函数:
# tidy data
library(tidyr)
df_tidy <- gather(df, key = series, value = values, num1:num2)
# plot with facets
ggplot(df_tidy, aes(values, fill = class)) +
geom_density(alpha = 0.2) +
facet_wrap(~series)