【发布时间】:2022-10-04 18:37:02
【问题描述】:
我的问题是,是否可以动态创建一个 geoms 列表,我可以将其添加到 ggplot 中,使我能够一次绘制多个单独的数据系列?
可重现的例子
以下代码演示了我的问题:
library(ggplot2)
# Function to generate fake data
generate_fake_results = function(){
results = list()
for(i in c(1:10)){
x = c((1+10*i):(10+10*i))
results = append(results, list(data.frame(
x = as.Date("2000-01-01") + x,
y = sin(x),
ylower1 = sin(x) - 0.25,
ylower2 = sin(x) - 0.5,
yupper1 = sin(x) + 0.25,
yupper2 = sin(x) + 0.50
)
)
)
}
return(results)
}
fake_data = generate_fake_results()
# Function to plot the mean, upper and lower bounds of a model
# The dataset contains two upper and lower bounds; the 80% and 95% confidence interval
predict_margin_func = function(r, color='blue', alpha=0.1){
return(
list(
geom_ribbon(aes(x=as.Date(r$x,"%Y-%m-%d"),
ymin=r$ylower1,
ymax=r$yupper1), fill=color, alpha=alpha),
geom_ribbon(aes(x=as.Date(r$x,"%Y-%m-%d"),
ymin=r$ylower2,
ymax=r$yupper2), fill=color, alpha=alpha),
geom_line(aes(x=as.Date(r$x,"%Y-%m-%d"), y=r$y), size=1.25, color=color)
)
)
}
# This plots the graph that I want, but... I have to manually add each forecast
# from my fake_data list "manually"
ggplot() +
predict_margin_func(fake_data[[1]]) +
predict_margin_func(fake_data[[2]]) +
predict_margin_func(fake_data[[3]]) +
predict_margin_func(fake_data[[4]]) +
predict_margin_func(fake_data[[5]])
# I'd rather use a for loop to do this dynamically, but I can't get it to work.
# If I do this, it doesn't work:
plot_list = list()
for(i in c(1:length(fake_data))){
plot_list = append(plot_list, predict_margin_func(fake_data[[i]]))
}
ggplot() +
plot_list
虽然解决方案 1“有效”,但我更愿意使用解决方案 2 之类的东西,我不必手动添加要绘制的每个系列,因为如果结果列表中的预测数量发生变化,这更容易扩展.
plot_list 中的结果似乎是 for 循环中最后一个结果/最高 i 的 10 个副本。我在质疑 R 正在做一些聪明的把戏,在这种特定情况下我不想要它,列表中的结果是事物的实例/引用,我想要“也被引用的事物”。
有谁知道我可以在这里做什么?我也许也可以重塑我的数据,但我想知道是否可以使用列表。
【问题讨论】:
-
您是否尝试过:
plot <- ggplot(),然后在循环内执行plot <- plot + predict_margin_func(...)? -
@GregorThomas,不是真的,可以添加一个 geoms 列表:
ggplot(mtcars, aes(mpg, disp)) + lapply(c(4,6,8), function(CYL) geom_point(data = ~ subset(., cyl == CYL), color = CYL))作品(尽管显然有更好的方法那)。 -
也许问题是您无法添加几何列表的列表...编辑,不,这也很好用。
-
@ImpactGuide,您是否有理由不能将数据(带有一些明确的 ID)和
facet_*或group=合并到该 ID 上? -
无论如何,我可以使用
ggplot() + lapply(fake_data, predict_margin_func)重现您的手动绘图(一旦我将fake_results重命名为fake_data)