想创建一个使用ggplot生成图形的函数.为简单起见,典型的图可以是
ggplot(car, aes(x=speed, y=dist)) + geom_point()
Run Code Online (Sandbox Code Playgroud)
我想要创建的函数是类型
f <- function(DS, x, y) ggplot(DS, aes(x=x, y=y)) + geom_point()
Run Code Online (Sandbox Code Playgroud)
然而,这不起作用,因为x和y不是字符串.在以前的SO问题中已经注意到这个问题(例如,这个问题),但在我看来,没有提供令人满意的答案.如何修改上面的函数使其适用于任意数据帧?
这个问题来自一系列其他问题,这些问题都涉及到同样的问题.出于某些奇怪的原因,在第二个函数中找不到第一个函数的局部环境中定义的变量的意义上,在另一个函数中使用函数有时会失败.
伪代码中的经典模式:
ff <- function(x){
y <- some_value
some_function(y)
}
ff(x)
Run Code Online (Sandbox Code Playgroud)
eval(expr,envir,enclos)中的错误:找不到对象'y'
首先我认为它与S4方法和那里的范围有关,但它也与其他函数一起发生.我和R开发团队进行了一些互动,但是他们所做的只是让我直接进入错误报告站点(我不得不说,这不是最吸引人的站点).我从来没有得到任何反馈.
随着问题不断出现,我想知道是否有一个逻辑解释.在所有这些情况下是否是一个常见的错误,如果是这样,哪一个?或者它真的是一个错误?
其中一些问题:
PS:我知道R-devel列表,万一你想知道......
请考虑以下代码:
test <- function(x,n){
selection<-names(x)[n]
graph <- ggplot(x, aes(factor(selection)))
graph + geom_bar()
}
test(mtcars,1)
Run Code Online (Sandbox Code Playgroud)
它抛出错误导致R无法找到选择.我也玩过周围substitute,eval并get没有成功.我发现了这个类似的问题,并且我认为我理解Joris'答案,但也不能对ggplot的参数使用相同的技巧.
考虑以下两个功能:
library(ggplot2)
testdata <- as.data.frame(cbind(rep(c(1, 4), each = 50), rbinom(100, 50, .5)))
names(testdata) <- c("group", "value")
plotfun1 <- function(color) {
ggplot(data = testdata, aes(x = factor(group, levels = c(0: 4)), y = value)) +
geom_boxplot(color = color)
}
plotfun2 <- function(number) {
ggplot(data = testdata, aes(x = factor(group, levels = c(0: number)), y = value)) +
geom_boxplot(color = 'red')
}
Run Code Online (Sandbox Code Playgroud)
Plotfun1完美地工作,打电话
plotfun1('red')
Run Code Online (Sandbox Code Playgroud)
产生两个漂亮的红色箱形图.但是打电话
plotfun2(4)
Run Code Online (Sandbox Code Playgroud)
产生错误消息:
因子中的错误(组,级别= c(0:数字)):找不到对象'数字'
显然在某些情况下ggplot无法"找到"函数的参数,在某些情况下它是.这里发生了什么?
PS我知道有一个简单的解决方法:
plotfun3 <- function(number) {
plotdata <- testdata
plotdata$group <- factor(plotdata$group, levels …Run Code Online (Sandbox Code Playgroud) 我有一个问题,但在此解决方案中找不到答案。我的意思是,我想ggplot在新函数中使用该函数,例如
library(ggplot2)
draw_point <- function(data, x, y ){
ggplot(data, aes_string(x, y)) +
geom_point()
}
Run Code Online (Sandbox Code Playgroud)
结果我必须使用引号:
draw_point(mtcars, "wt", "qsec")
Run Code Online (Sandbox Code Playgroud)
相反,我想使用某种lazyeval包来编写这个不带引号的函数:
draw_point(mtcars, wt, qsec)
Run Code Online (Sandbox Code Playgroud)
有可能做到吗?
下面的工作,它根据数据的顺序绘制一列数据:
s<-data.frame(t=c(3, 50, 20, 100, 7, 80))
ggplot(s, aes(y=s$t, x=seq(1, length(s$t)))) +
geom_point()+
geom_hline(yintercept =10)
Run Code Online (Sandbox Code Playgroud)
因为我有很多这样的数据,所以我想将其放在一个函数中以便可以重用,如下所示:
plot1<-function(a, b, c){
ggplot(a, aes(y=a$b, x=seq(1, length(a$b)))) +
geom_point()+
geom_hline(yintercept =c)
}
Run Code Online (Sandbox Code Playgroud)
但是,以下操作无效:
s<-data.frame(t=c(3, 50, 20, 100, 7, 80))
plot1(s, t, 10)
Run Code Online (Sandbox Code Playgroud)
而是,它产生以下错误消息:错误:美学必须为长度1或与数据(6)相同:x,y
什么地方出了错?