函数内的ggplot2变量

时间:2014-06-12 19:01:42

标签: r

感觉我在这里犯了一个非常愚蠢的错误......因为我之前在另一个项目上做过这个(也许运气好吗?)

目标是通过使用函数在ggplot中构建几个图形。我最终希望所有图表都显示在一个页面上等等......

以下是一个有效的单个ggplot示例:

if (require("ggplot2") == FALSE) install.packages("ggplot2")

data_df = data.frame(matrix(rnorm(200), nrow=20))
time=1:nrow(data_df)

ggplot(data=data_df, aes(x=time, y=data_df[,1])) + 
        geom_point(alpha=1/4) + 
        ggtitle(deparse(substitute(data_df[1])))

请注意,在此范围内将调用其他函数,这些函数将根据调用的dataframe列进行更改。 我按照我做的另一个工作示例,但这只是给了我一个错误。我觉得我犯了一个基本的错误,但不能指责它!

if (require("ggplot2") == FALSE) install.packages("ggplot2")

data_df = data.frame(matrix(rnorm(200), nrow=20))
time=1:nrow(data_df)

graphit <- function(sample_num){
        ggplot(data=data_df, aes(x=time, y=data_df[,sample_num])) + 
                geom_point(alpha=1/4) + 
                ggtitle(deparse(substitute(data_df[sample_num])))
}

graphit(1)

#Error in `[.data.frame`(data_df, , sample_num) : 
#  object 'sample_num' not found

感谢您的帮助。

2 个答案:

答案 0 :(得分:8)

你做错了几件事。

首先,aes()中指定的所有内容都应该是数据框中的列。不要引用单独的向量,也不要通过data_df[,1]冗余调用列。指定data = data_df的重点是,aes()内的所有内容都在 数据框内进行评估。

其次,要根据参数编写在不同列上创建ggplot的函数,您应该使用aes_string,这样您就可以将美学映射明确地作为字符传递,避免出现非标准问题评价。

同样,我不会依赖deparse(substitute())作为情节标题。使用内置于数据框或其他一些数据结构中的其他变量。

例如,我会做更像这样的事情:

data_df = data.frame(matrix(rnorm(200), nrow=20))
time=1:nrow(data_df)
data_df$time <- time

graphit <- function(data,column){
    ggplot(data=data, aes_string(x="time", y=column)) + 
        geom_point(alpha=1/4) + 
        ggtitle(column)
}

graphit(data_df,"X1")

答案 1 :(得分:1)

由于重复计数而无法发表评论。强烈推荐Joran的解决方案(以及对ggplot2的建议)。

这是一个非常不推荐的hack,可以让你的代码工作。将此行添加为函数的第一行。

assign(x = "sample_num", value = sample_num, envir=.GlobalEnv)

上述相同代码的替代合成器是sample_num <<- sample_num

您面临的问题是范围问题。 sample_num仅存在于graphit()环境中,未在ggplot()环境中定义。