我已经在Windows 10机器上安装了一个新的R安装程序,并且不能运行以下简单的程序:
data.frame(a = rnorm(100), b = rnorm(100)) |>
ggplot(aes(a, b)) +
ggsave("temp.png")
因为我得到了以下错误:
Error: Can't add `ggsave("temp.png")` to a ggplot object.
我的会议信息是:
R version 4.1.0 (2021-05-18)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Matrix products: default
locale:
[1] LC_COLLATE=Catalan_Spain.1252 LC_CTYPE=Catalan_Spain.1252 LC_MONETARY=Catalan_Spain.1252 LC_NUMERIC=C
[5] LC_TIME=Catalan_Spain.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggplot2_3.3.4 dplyr_1.0.6
loaded via a namespace (and not attached):
[1] magrittr_2.0.1 tidyselect_1.1.1 munsell_0.5.0 colorspace_2.0-1 R6_2.5.0 rlang_0.4.11 fansi_0.5.0 tools_4.1.0
[9] grid_4.1.0 data.table_1.14.0 gtable_0.3.0 utf8_1.2.1 withr_2.4.2 ellipsis_0.3.2 digest_0.6.27 tibble_3.1.2
[17] lifecycle_1.0.0 crayon_1.4.1 purrr_0.3.4 farver_2.1.0 vctrs_0.3.8 glue_1.4.2 labeling_0.4.2 compiler_4.1.0
[25] pillar_1.6.1 generics_0.1.0 scales_1.1.1 pkgconfig_2.0.3
我已经将权限授予了我正在处理的目录,并在不同的目录中尝试使用RScript、RStudio和Pycharm控制台运行,始终存在相同的问题。
提前谢谢。
编辑:这曾经适用于ggplot2 3.3.3,它是对3.3.4的更新破坏了一切。
发布于 2021-06-16 13:34:24
您可以不再“添加”ggsave
到一个ggplot添加-管道。
编辑:这是ggplot2-3.3.4
的最新变化。如果您想要处理新的行为,前面的答案将保留在下面。如果您对此感到特别恼火,您可能会向ggplot2
提交一个新的问题,建议他们要么(a)撤消中断的更改,要么(b)更好地记录非预期功能中的更改。
边注:在这个答案发布后的第二天,提交389b864包含了以下文本:“注意,作为一个副作用,一个非官方的黑客
<ggplot object> + ggsave()
不再工作(#4513)。”
(事实上,我不记得有文档表明+ ggsave(.)
应该工作,所以对新问题的反应可能是他们不想为了放弃其他一些优雅的完整性而保留一个意想不到的“特性”。)
来自3.3.3至3.3.4 (对于save.R
)的更改大多与保存文件的操作无关。但是,一个功能更改是来自ggsave
的返回值。
@@ -90,5 +98,5 @@ ggsave <- function(filename, plot = last_plot(),
grid.draw(plot)
- invisible()
+ invisible(filename)
}
回顾一下,这是有意义的:ggplot2
使用+
-pipes的能力通常可以尝试添加NULL
-like对象。也就是说,这是没有错误的:
data.frame(a = rnorm(100), b = rnorm(100)) |>
ggplot(aes(a, b)) +
NULL
为什么NULL
在这里有关联?因为上一个版本(3.3.3)的ggsave
以invisible()
结尾,这是在无形地返回NULL
。(在内部,ggplot2:::add_ggplot
以if (is.null(object)) return(p)
开头,这解释了为什么工作。)
然而,随着对invisible(filename)
的更改(实际上,imo更好一些),这实际上与
data.frame(a = rnorm(100), b = rnorm(100)) |>
ggplot(aes(a, b)) +
"temp.png"
这没有道理,所以+
-piping失败了。
在ggplot2-3.3.3
中,可以用黑客/丑陋代码复制此错误:
data.frame(a = rnorm(100), b = rnorm(100)) |>
ggplot(aes(a, b)) +
{ ggsave("temp.png"); "temp.png"; }
# Error: Can't add `{` to a ggplot object.
# * Can't add ` ggsave("temp.png")` to a ggplot object.
# * Can't add ` "temp.png"` to a ggplot object.
# * Can't add `}` to a ggplot object.
这非常接近您看到的错误(我相信)证明了我的观点:新的和改进的ggplot2-3.3.4返回一个字符串,这足以打破将ggsave
添加到ggplot2对象的习惯模式。
如果要向ggplot2提交一个新的问题,那么我建议将其作为一个“特性请求”:如果invisible(filename)
是一个+
工作的类对象,那么可以保留之前的行为,同时仍然支持字符串返回。例如(完全未经测试):
ggsave <- function(file, ...) {
# .....
class(filename) <- c("ggplot2_string", "character")
invisible(filename)
}
然后将+.gg
-logic扩展到实际用于字符串,可能类似于
`+.gg` <- function (e1, e2) {
if (missing(e2)) {
abort("Cannot use `+.gg()` with a single argument. Did you accidentally put + on a new line?")
}
if (inherits(e2, "ggplot2_string")) {
e2 <- NULL
e2name <- "NULL"
} else {
e2name <- deparse(substitute(e2))
}
if (is.theme(e1))
add_theme(e1, e2, e2name)
else if (is.ggplot(e1))
add_ggplot(e1, e2, e2name)
else if (is.ggproto(e1)) {
abort("Cannot add ggproto objects together. Did you forget to add this object to a ggplot object?")
}
}
不,我不认为这是最好的方法,但这是一种方式,开放讨论。
你可以做四件事:
plot=
参数。虽然我还没有R-4.1,但基于评论,我相信虽然|>
总是将前一个结果作为下一个调用的第一个参数传递,但是您可以通过命名file=
参数来解决这个问题,这意味着R-4.1将传递给第一个可用的参数,在这个例子中,这个参数恰好是plot=
,这正是我们所需要的。
data.frame(a = rnorm(100),b= rnorm(100)) |> ggplot(aes(a,b)) |> ggsave(file = "temp.png")发布于 2021-06-16 13:30:42
只要移除加号。
data.frame(a = rnorm(100), b = rnorm(100)) |>
ggplot(aes(a, b))
ggsave("temp.png")
ggsave具有默认输入last_plot()
。
发布于 2021-10-12 00:21:35
我不知道我的设置是否在某种程度上与其他设置不同,或者这是否只是我的ggsave代码被配置的方式,但它仍然对我起作用,同时也启动了错误。
在这中,托马斯说:
首先,虽然您将在v3.3.4中得到一个错误,但是这个图实际上被保存到一个文件中,因为该错误是在ggsave()的计算后抛出的。这意味着您可以通过将整个表达式放在try()块中来“修复”代码(请不要这样做)。
但你不需要做试块。我的代码块是:
ggplot(stuff) +
ggsave(paste0(today(), "_PlotName", ".png"),
plot = last_plot(),
device = "png", path = "", scale = 3.5, width = 8,
height = 4, units = "in", dpi = 300, limitsize = TRUE)
可以推测,指定plot = last_plot()
会使事情继续工作。但不要告诉任何人,以防他们拿走它;)
https://stackoverflow.com/questions/68003633
复制相似问题