Это всего лишь частичный ответ относительно одного аспекта проблемы.
Когда вы помещаете yintercept
в функцию aes()
, вы даете команду ggplot2 сопоставить yintercept
aestheti c в каждую строку аргумента data
. Следовательно, слой geom_hline()
преобразует свои данные в большой data.frame, содержащий много строк. Если вы не поместите его в функцию aes()
, а используете в качестве обычного аргумента слоя, данные слоя останутся небольшими. См. Пример ниже.
library(ggplot2)
numRows <- 1e6
df <- data.frame( x1 = runif(numRows), x2 = runif(numRows), xGroup = factor(trunc(runif(numRows, 1, 6))) )
df$y = df$x1 + df$x2
p <- ggplot( data = df, mapping = aes( x = x1)) +
geom_smooth( mapping = aes( y = y))
p_mapped <- p + geom_hline(mapping = aes(yintercept = 0.25))
p_unmapped <- p + geom_hline(yintercept = 0.25)
layer_mapped <- layer_data(p_mapped, 2)
#> `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
layer_unmapped <- layer_data(p_unmapped, 2)
#> `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
(format(object.size(layer_mapped), units = "Mb"))
#> [1] "42 Mb"
(format(object.size(layer_unmapped), units = "Kb"))
#> [1] "2.2 Kb"
Обратите внимание, что хотя размер данных слоя не учитывает большую часть используемой памяти, нужно иметь в виду, что многие вещи вычисляются на основе данных, начиная с вычисления по осям, чтобы применить альфа-канал к цветам.
Кроме того, запустив ваш пример и изменив место, где yintercept
было определено из аргумента сопоставления на обычный аргумент слоя, endMemSize
было около ~ 200Мб для меня.
Наконец, ggplot2 хранит копию последнего графика в своем пространстве имен, которая не видна пользователям. Однако вы можете использовать set_last_plot(NULL)
, чтобы освободить дополнительную память.