我想使用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)
,但是当我这样做时,我会收到一条错误消息,说“&#39; value&#39;没找到。我怀疑问题与刻面有关,但我更愿意保持我的方面。
在这种情况下,如何缩放和移动密度曲线?
答案 0 :(得分: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))
答案 1 :(得分:2)
我不确定这是否完全回答了你的问题,但是发表评论的时间太长了,所以...回答你问题中的第二大块代码,因为你已经定义了{{ 1}},您可以在y的定义中使用x=value
代替x
。
value
这似乎可以解决您的错误并产生以下情节:
唯一的问题当然是,如果您的数据具有较低的y值,那么您仍然会将密度曲线与散点图重叠。但是,如果不是这种情况,我个人认为这是一个相当翔实的数字,只要你能有效地沟通,y轴值在解释密度曲线时并不重要 - 只有曲线的形状是重要的。
答案 2 :(得分:0)
我很欣赏每个人的答案,这让我更好地理解了ggplot底层机制。我也意识到我的要求有多尴尬; ggplot不会解决我的问题。
我设法做了我想要的不是通过使用ggplot stat_density
,而是直接计算我在另一个数据框中的密度:
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
的构造有点混淆,但我稍后会继续讨论。)
为了你的麻烦,我会在当天结束时向最有投票的解决方案发放奖金。