Ответ 1
Лично я считаю, что создание фреймов данных и использование geom_ribbon
- элегантное решение, но, судя по всему, мнения будут отличаться от этого.
Но если вы в полной мере воспользуетесь plyr и ggplot, все может стать довольно гладким. Так как ваши склоны и перехваты все хорошо хранятся в фреймворке данных, мы можем использовать plyr и пользовательскую функцию для выполнения всей работы:
dat <- data.frame(cond1=c("a","a","b","b"),
cond2=c("c","d","c","d"),
x=c(1,5),
y=c(1,5),
sl=c(1,1.2,0.9,1.1),
int=c(0,0.1,0.1,0),
slopeU=c(1.1,1.3,1.2,1.2),
slopeL=c(.9,1,0.7,1))
genRibbon <- function(param,xrng){
#xrng is a vector of min/max x vals in original data
r <- abs(diff(xrng))
#adj for plot region expansion
x <- seq(xrng[1] - 0.05*r,xrng[2] + 0.05*r,length.out = 3)
#create data frame
res <- data.frame(cond1 = param$cond1,
cond2 = param$cond2,
x = x,
y = param$int + param$sl * x,
ymin = param$int + param$slopeL * x,
ymax = param$int + param$slopeU * x)
#Toss the min/max x vals just to be safe; needed them
# only to get the corresponding y vals
res$x[which.min(res$x)] <- -Inf
res$x[which.max(res$x)] <- Inf
#Return the correspondinng geom_ribbon
geom_ribbon(data = res,aes(x = x,y=y, ymin = ymin,ymax = ymax,
fill = cond1,colour = NULL),
alpha = 0.5)
}
ribs <- dlply(dat,.(cond1,cond2),genRibbon,xrng = c(1,5))
Дополнительным преимуществом здесь является то, что я полностью отбрасываю сгенерированные кадры данных и просто возвращаю список объектов geom_ribbon
. Затем их можно просто добавить в наш сюжет:
p + ribs +
guides(fill = guide_legend(override.aes = list(alpha = 0.1)))
Я превзошел эстетику alpha
в легенде, потому что в первый раз вокруг вас не было видно диагональных линий в легенде.
Я предупреждаю вас, что последняя строка, которая генерирует графики, также содержит множество предупреждений о недопустимых уровнях факторов, и я честно не знаю, почему. Но сюжет выглядит нормально.