多个组的箱线图和回归曲线

时间:2014-07-10 11:09:21

标签: r ggplot2 boxplot

我想制作比较不同树种群增长的情节。

library(MASS)
library(datasets)
library(ggplot2)
library(plyr)
library(grofit)

# Create groups as areas
Loblolly$Area = round(as.integer(as.character((Loblolly$Seed)))/10)
# factors for boxplot
Loblolly$fArea = factor(Loblolly$Area)
Loblolly$fAge  = factor(Loblolly$age)

# Regression curve fitting
fHeight <- nls(height ~ gompertz(age,as,x1,x2), start=list(as=60,x1=1,x2=10), 
               data = ddply(Loblolly, c("age"), summarise, height = mean(height))
)

# A separate data frame for draw the fitted curves
age <- 1:25
lHeight <- predict(fHeight, list(age=age))
dfLine <- data.frame(age, lHeight)

ggplot(data=Loblolly, aes(x=fAge, y=height, fill=fArea)) +
  geom_jitter(colour="lightgray") +
  geom_boxplot() 

我可以创建像这样的箱形图:

HeightChart

但我想为每个fArea组拟合单独的拟合曲线,并将这些曲线放在箱线图上。

当我使用“填充”选项将参数组作为箱线图显示时,我无法使用另一个data.frame作为“geom_line”叠加层。

如何为每个组提供符合geom_line的拟合gompertz函数?

1 个答案:

答案 0 :(得分:1)

因为每个age的{​​{1}}值都相同,所以每个fArea的拟合线与您的模型现在相同。如果您希望每组具有不同的拟合,则需要首先根据fArea拟合单独的模型。有很多方法可以做到这一点,一个例子是here。这将为列表中的每个组存储模型。

我最终制作了摘要数据集,因此按fArea排序,这使我更容易将fArea的预测添加到fArea

Lob2

然后,我使用# Make a summary dataset, ordered by fArea Lob2 = ddply(Loblolly, .(fArea, age), summarize, height = mean(height)) # Function to fit the model by group f = function(s) nls(height ~ gompertz(age,as,x1,x2), start=list(as=60,x1=1,x2=10), data = Lob2, subset = Lob2$fArea == s) # Fit the model by group, save as a list mods = sapply(levels(Lob2$fArea), f, simplify = FALSE) 对列表中的每个模型进行预测,使用拟合预测中使用的数据(这是lapply中的默认值)并将其添加到predict }。这种方法的缺点(在我看来,无论如何)是数据集的顺序我将预测添加到事项中所以我必须小心。

Lob2

要将连续线添加到在x轴上具有因子的图形有点尴尬。我发现this link显示了如何做到这一点。然而,这种方法使得拟合曲线比理想情况下更不平滑。也许跳过箱形图并按Lob2$lHeight = unlist(lapply(mods, predict)) 着色点是一个合理的选择?

fArea

编辑以添加来自其他数据集的预测

以下是从模型列表中的新数据集进行预测的一种方法。由于您希望单独绘制每个ggplot(data = Loblolly, aes(x = fAge, y = height, fill = fArea)) + geom_jitter(colour="lightgray") + geom_boxplot() + geom_line(data = Lob2, aes(x = as.numeric(ordered((age)), y = lHeight, color = fArea)) 模型的图形,因此将fArea保留在新数据集中很方便。我再次按fArea保持新数据集。

fArea

现在我再次使用# Predict with new data.frame (keeping in order by fArea again) newdat = expand.grid(age = 1:25, fArea = levels(Lob2$fArea)) 来浏览lapply的每个level,并使用fArea的相应子集从每个fArea模型进行预测。我将预测添加到newdat以便于绘图。数据集必须按newdat按顺序排列,以便在编码时正常工作。

fArea

您可能会发现很难将其绘制为x轴上的连续线,这是基于6个值的因素 - 这就是我专注于仅对原始数据进行预测的原因。另一种方法是摆脱箱形图,并通过分组变量为点和线着色。

newdat$lHeight = unlist(lapply(levels(Lob2$fArea), function(x) {
    predict(mods[[x]], newdata = newdat[newdat$fArea == x,]) } ))