4

我想使用 facet_wrap 将一些数据绘制为散点图,同时叠加一些信息,例如线性回归和密度。我设法做到了所有这些,但是密度值与我的点不成比例,这是正常的事情,因为这些点很远。不过,我想缩放和移动我的密度曲线,使其清晰可见;我不关心它的真实价值,而是更关心它的形状。

这是我所拥有的一个夸张的最小工作示例:

set.seed(48151623)
mydf <- data.frame(x1=rnorm(mean=5,n=100),x2=rnorm(n=100,mean=10),x3=rnorm(n=100,mean=20,sd=3))
mydf$var <- mydf$x1 + mydf$x2 * mydf$x3 
mydf.wide  <- melt(mydf,id.vars='var',measure.vars=c(1:3))
ggplot(data=mydf.wide,aes(x=value,y=var)) +
  geom_point(colour='red') +
  geom_smooth(method='lm') +
  stat_density(aes(x=value,y=..scaled..),position='identity',geom='line') +
  facet_wrap(~variable,scale='free_x')

结果是: 当前绘图示例

我想要的类似于这个丑陋的黑客:

stat_density(aes(x=value,y=..scaled..*100+200),position='identity',geom='line')

理想情况下,我会使用y=..scaled..* diff(range(value)) + min(value),但是当我这样做时,我收到一个错误,提示找不到“价值”。我怀疑这个问题与刻面有关,但我更愿意保留我的刻面。

在这种情况下如何缩放和移动密度曲线?

很酷的结果,但丑陋的黑客

4

3 回答 3

6

我建议制作两个图并将它们与grid.arrange

p1 <- ggplot(data=mydf.wide,aes(x=value,y=var)) +
  geom_point(colour='red') +
  geom_smooth(method='lm') +
  facet_wrap(~variable,scale='free_x') +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        plot.margin =       unit(c(1, 1, 0, 0.5), "lines"))

p2 <- ggplot(data=mydf.wide,aes(x=value,y=var)) +
  stat_density(aes(x=value,y=..scaled..),position='identity',geom='line') +
  facet_wrap(~variable,scale='free_x') + 
  theme(strip.background=element_blank(),
        strip.text=element_blank(),
        plot.margin =       unit(c(-1, 1, 0.5, 0.35), "lines"))

library(gridExtra)
grid.arrange(p1, p2, heights = c(2,1))

在此处输入图像描述

于 2013-07-15T07:58:59.297 回答
2

我不确定这是否完全回答了您的问题,但是发表评论的时间太长了,所以...响应您问题中的第二段代码,因为您已经定义了x=value,您可以x改用在value你对 y 的定义中。

stat_density(aes(x=value,y=..scaled..*diff(range(x)) + 
min(x)),position='identity',geom='line')

这似乎可以解决您的错误并产生以下情节:

在同一 y 轴上具有密度曲线的多面散点图

当然,唯一的问题是,如果您有低 y 值的数据,那么您仍然会将密度曲线与散点图重叠。但是,如果不是这种情况,我个人认为这是一个相当有用的数字,只要你能有效地传达 y 轴值在解释密度曲线时并不重要——只有曲线的形状是重要的。

于 2013-07-14T20:14:34.033 回答
0

感谢大家的回答,让我对ggplot底层机制有了更好的理解。我也意识到我的要求有多尴尬;ggplot 不会解决我的问题。stat_density我设法通过使用 ggplot而不是直接计算我在另一个数据框中的密度来做我想做的事情:

set.seed(48151623)
mydf <- data.frame(x1=rnorm(mean=5,n=100),x2=rnorm(n=100,mean=10),x3=rnorm(n=100,mean=20,sd=3))
mydf$var <- mydf$x1 + mydf$x2 * mydf$x3 
mydf.wide  <- melt(mydf,id.vars='var',measure.vars=c(1:3))

mydf.densities <- do.call('rbind',lapply(unique(mydf.wide$variable), function(var) {
  tmp <- mydf.wide[which(mydf.wide$variable==var),c('var','value')]
  dfit <- density(tmp$value,cut=0)
  scaledy <-dfit$y/max(dfit$y) * diff(range(tmp$var)) + min(tmp$var)
  data.frame(x=dfit$x,y=scaledy,variable=rep(var,length(dfit$x)))
}))
ggplot(data=mydf.wide,aes(x=value,y=var)) +
  geom_point(colour='red') +
  geom_smooth(method='lm') +
  geom_line(aes(x=x,y=y),data=mydf.densities) +
  facet_wrap(~variable,scale='free_x')

(我知道 的构造mydf.densities有点模糊,但我稍后会处理)。

为了您的麻烦,我在一天结束时将赏金奖励给投票最多的解决方案。

我想做的情节

于 2013-07-15T11:07:21.697 回答