读取小插图Programming with dplyr时,我尝试使用List<String>
和...
运算符来实现一个函数,该函数将环绕ggplot函数,并接受任意数量的参数来定义哪个参数数据框中的变量应映射到每种美感。
我想定义一个函数!!!
使得
plot_points2()
等同于plot_points2(df, x = x, y = y, color = z)
df %>% ggplot( mapping = aes(x = x, y = y, color = z) ) + geom_point(alpha = 0.1)
等同于plot_points2(df, x = x, y = z, color = y)
df %>% ggplot( mapping = aes(x = x, y = z, color = y) ) + geom_point(alpha = 0.1)
等同于plot_points2(df, x = x, y = z)
df %>% ggplot( mapping = aes(x = x, y = z) ) + geom_point(alpha = 0.1)
require(tidyverse)
require(rlang)
df <- tibble(g1= sample(x = c(1,2,3), replace = T, size = 10000),
g2= sample(x = c("a","b","c"), replace = T, size = 10000),
x = rnorm(10000, 50, 10),
y = rnorm(10000, 0, 20) + x*2,
z = rnorm(10000, 10, 5))
df
plot_points2 <- function(d, ...){
args <- quos(...)
print(args)
ggplot(data = d, mapping = aes(!!!args)) + geom_point(alpha = 0.1)
}
plot_points2(df, x = x, y = y, color = z)
我认为我要完成的操作与vignette中的示例没有太大不同,该示例使用这些运算符来制作一个环绕Error: Can't use `!!!` at top level
Call `rlang::last_error()` to see a backtrace
的函数,并传递定义分组的多个参数变量(实际上,我能够实现一个功能,对上面我作为示例发布的示例数据集执行此功能),但是后者以某种方式起作用而前者却不起作用:
mutate()
add_dif_to_group_mean <- function(df, ...) {
groups <- quos(...)
df %>% group_by(!!!groups) %>% mutate(x_dif = x-mean(x),
y_dif = y-mean(y),
z_dif = z-mean(z))
}
df %>% add_dif_to_group_mean(g1)
df %>% add_dif_to_group_mean(g1, g2)
我还读到,问题可能与plot_points2 <- function(d, ...){
args <- quos(...)
print(args)
ggplot(data = d, mapping = aes(!!!args)) + geom_point(alpha = 0.1)
}
plot_points2(df, x = x, y = y, color = z)
仅在打印打印图时才被评估有关,但在这种情况下,我认为手动使用aes()
和拆箱会产生相同的错误但不是:
!!
实际上,如果绘制3个变量,则最后一个示例可以正常工作,但不允许绘制多个3个变量以外的变量
例如:plot_points2b <- function(d, ...){
args <- quos(...)
print(args)
ggplot(data = d, mapping = aes(x = !!args[[1]],
y = !!args[[2]],
color = !!args[[3]])) +
geom_point(alpha = 0.1)
}
plot_points2b(df, x = x, y = y, color = z)
不等于
plot_points2b(df, x = x, y = z)
相反,它会引发错误:
df %>% ggplot( mapping = aes(x = x, y = z) ) + geom_point(alpha = 0.1)
有人知道我在这里想念什么概念吗?预先谢谢你!
答案 0 :(得分:1)
您的特定用例是?aes
中的一个示例。 aes
自动引用其参数。可以简单地直接传递点。试试:
plot_points3 <- function(d, ...){
print(aes(...))
ggplot(d, aes(...)) + geom_point(alpha = 0.1)
}
plot_points3(df, x = x, y = y, color = z)
这很好地打印:
Aesthetic mapping: * `x` -> `x` * `y` -> `y` * `colour` -> `z`
并生成所需的图。
答案 1 :(得分:0)
如我的评论中所述,我认为您的环境中可能已经有x和y,这就是为什么某些代码可以正常工作的原因。我不确定您要实现的目标,但我认为您为使代码无错误运行而付出了太多努力。
例如:
plot_points <- function(d, ...){
ggplot(data = d, mapping = aes(x = x, y = y)) +
geom_point(alpha = 0.1)
}
plot_points (df, x, y)
将使您的绘图无任何理由增加!!!
或enquo()
的开销和复杂性。
您也在这里,这条更简单的代码可以正常工作:
add_dif_to_group_mean <- function(., ...) {
df %>% group_by(g1) %>% mutate(x_dif = x-mean(x),
y_dif = y-mean(y),
z_dif = z-mean(z))
}
df %>% add_dif_to_group_mean(g1)
类似:
plot_points2 <- function(d, ...){
ggplot(data = d, mapping = aes(x=x, y=y, color=z)) +
geom_point(alpha = 0.1)
}
plot_points2(df, x = x, y = y, color = z)
据我所知工作正常。
所以我知道也许您正在研究本书中的示例,这很棒。但是我认为某个地方存在一个遗漏的问题,因此您必须在现实世界中执行所有其他工作。例如,也许您想传递诸如"x"
和"y"
之类的字符串而不是x
和y
?