是否有一种从ggplot_build()
(或任何其他函数)中搜索整个输出的方法,就像搜索文件夹中每个子目录的完整内容一样?
详细信息:
我一直在寻找Retrieve values for axis labels in ggplot2_3.0.0的解决方案,早期的答案之一表明,根据ggplot2
版本,正确答案很可能包含$layout
部分和/或$x.labels
输出中的ggplot_build(g)
。因此,我开始检查ggplot_build()
输出的每一步。步骤之一看起来像下面的输出。
代码段1:
ggplot_build(g)$layout
输出1:
<ggproto object: Class Layout, gg>
coord: <ggproto object: Class CoordCartesian, Coord, gg>
aspect: function
clip: on
[...]
map_position: function
panel_params: list
panel_scales_x: list
panel_scales_y: list
render: function
[...]
ylabel: function
super: <ggproto object: Class Layout, gg>
>
在panel params
下的x.labels
中可以找到ggplot_build(g)$layout$panel_params
以及许多有用的信息,如下所示:
代码段2:
[[1]]
[[1]]$`x.range`
[1] 7.7 36.3
[[1]]$x.labels
[1] "10" "15" "20" "25" "30" "35"
[[1]]$x.major
[1] 0.08041958 0.25524476 0.43006993 0.60489510 0.77972028 0.95454545
输出2:
ggplot_build(g)$layout$panel_params[[1]]$x.labels
它可以像这样直接引用:
代码段3:
[1] "10" "15" "20" "25" "30" "35"
输出3:
capture.output()
我尝试采用更优雅的方法:
我确定我可以像here一样使用str()
来完成此操作,但是据我所知,您找不到{{1} }那里。我不会用这个输出来充斥这个问题,因为它大约有300行。
谢谢您的任何建议!
答案 0 :(得分:3)
此函数遍历嵌套列表结构,并查找通过该结构的包含给定字符串的路径:
find_name <- function(obj, name) {
# get all named paths through obj
find_paths <- function(obj, path) {
if ((!is.list(obj) && is.null(names(obj))) || identical(obj, .GlobalEnv)) {
return (path)
} else {
if (is.null(names(obj))) {
return(c(path,
lapply(seq_along(obj), function(x) find_paths(obj[[x]], paste0(path, "[[", x, "]]")))
))
} else {
return(c(path,
lapply(names(obj), function(x) find_paths(obj[[x]], paste(path, x, sep = "$")))
))
}
}
}
# get all the paths through the nested structure
all_paths <- unlist(find_paths(obj, deparse(substitute(obj))))
# find the requested name
path_to_name <- grep(paste0("\\$", name, "$"), all_paths, value = TRUE)
return (path_to_name)
}
以下是将此功能与ggplot_built
对象一起使用的示例:
library(ggplot2)
p <- ggplot(mtcars) + geom_point(aes(x = disp, y = mpg, col = as.factor(cyl)))
gb <- ggplot_build(p)
find_name(gb, "x.labels")
## [1] "gb$layout$panel_params[[1]]$x.labels"
您还可以直接获取x.labels
的内容:
eval(parse(text = find_name(gb, "x.labels")))
## [1] "100" "200" "300" "400"
有关其工作原理的几点评论:
find_paths()
遍历嵌套结构,并以类似于"gb$layout$panel_params[[1]]$x.labels"
的形式返回通过该结构的所有“路径”。FALSE
和环境返回is.list()
。必须照顾所有这些情况。 ggplot_built
包含对全局环境(gb$layout$facet_params$plot_env
)的引用,如果处理不当,则会导致无限循环。find_paths()
的结果再次是一个嵌套列表,但是使用unlist()
可以轻松简化结构。find_name(gb, "x")
将不会返回"gb$layout$panel_params[[1]]$x.labels"
。我已经用示例中的ggplot_built
对象和嵌套列表测试了该功能。我不能保证它在所有情况下都有效。