通过x和y绘制第三个变量的平滑平均值

时间:2017-02-01 20:11:31

标签: r plot ggplot2

我正在尝试制作一个二维图,其中x和y轴是预测变量。我想平滑地总结第三个变量,因为特定坐标的计数非常低。

例如,我可能想要绘制违约概率与资产和债务的关系。这类似于密度图,但不是绘制观察的平滑密度,而是绘制任意平滑值,例如默认率。

我已尝试在stat_density_2d中使用ggplot2,但尚未弄清楚如何将第三个变量汇总为"密度"而不是观察计数。

示例数据:

data(iris)
plt <- data.frame(iris[c(1,2)], y=as.numeric(iris$Species == "setosa"))

我希望输出看起来像这样:

library(ggplot2)

ggplot(plt, aes(x=Sepal.Length, y=Sepal.Width)) + 
  stat_density_2d(aes(fill= ..density..), geom="tile", contour=FALSE)

enter image description here

但不是代表观察密度的颜色。我希望它代表一个汇总变量。在这种情况下,物种的概率==&#34; setosa&#34;

1 个答案:

答案 0 :(得分:2)

UPDATE2:基于discussion in chat,您看起来就像是指二维内核平滑功能。 smoothie package可能会满足您的需求。

无论您如何估计贷款违约概率(在下面给出{x,y)点(例如,平均值为分组的平均值,我将其称为填充颜色的变量,我在下面称为p.default)逻辑回归,内核平滑等),您可以使用以下内容创建绘图:

ggplot(df, aes(assets, debt, fill=p.default)) + geom_tile() 

更新:对于您的评论,对于iris示例,您需要对Sepal.LengthSepal.Width区域的y值求平均值平均概率。这些数据相当稀疏,因此您需要相对较大的细胞才能获得每个细胞多次观察。此外,Sepal.LengthSepal.Width落在每个物种几乎完全不同的区域,因此您几乎所有单元格中仍然会获得全部1或全0。在下面的例子中,我只是分配1和0的随机值,以便在几个单元格中混合使用1和0。

library(ggplot2)
library(dplyr)

# Fake data
set.seed(5)
plt <- data.frame(iris[c(1,2)], y=sample(0:1, nrow(iris), replace=TRUE))

在下面的代码中,我们使用cut函数将Sepal.LengthSepal.Width分别切成10个范围。然后我们平均每个单元格中的1和0以获得每个单元格的y的平均值。然后,此平均y值由填充颜色渐变表示。

plt %>% group_by(Sepal.Length = cut(Sepal.Length, 10),
                 Sepal.Width = cut(Sepal.Width, 10)) %>%
  summarise(y=mean(y)) %>%
  ggplot(aes(Sepal.Width, Sepal.Length, fill=y)) +
  geom_tile() + 
  theme_classic()

enter image description here

或者,我们可以使用逻辑回归模型,它可以为ySepal.Length的任意组合提供Sepal.Width的预测:

# Logistic regression model
m1 = glm(y ~ poly(Sepal.Length,2)*poly(Sepal.Width,2), family="binomial", data=plt)

# Get predictions on a grid of values
df = expand.grid(Sepal.Length=seq(4,8,length=100), Sepal.Width=seq(2,5,length=100))
df$y.pred = predict(m1, newdata=df, type="response")

ggplot(df, aes(Sepal.Width, Sepal.Length, fill=y.pred)) +
  geom_tile() + 
  theme_classic() +
  scale_fill_gradient2(low="blue",mid="yellow",high="red", midpoint=0.5,limits=c(0,1))

enter image description here

一般的想法是,您需要一个值(让我们称之为z)与图表上的每个(x,y)点相关联。您可以通过对(x,y)平面中的区域,模型等求平均值来计算这些z值。一旦得到z值与每个(x,y)点一致,您可以生成zfill美学的图块。

原始答案

听起来好像你想要一张热图。填充颜​​色将表示第三个变量的值,在这种情况下是默认概率。也许是这样的:

library(ggplot2)

# Fake data
df = expand.grid(income=seq(1,1e5,length=100), debt=seq(1,5e5,length=100))
df$p.default = df$income - 0.3*df$debt
df$p.default = df$p.default - max(df$p.default)
df$p.default = abs(df$p.default)/max(abs(df$p.default))

ggplot(df, aes(income, debt, fill=p.default)) + 
  geom_tile() +
  scale_fill_gradient2(limits=c(0,1), low="blue", mid="yellow", high="red", midpoint=0.5)

enter image description here