我意识到这个问题在这里已经以类似的方式被问过多次了。我不是要求一个散点图,其中包括数据的密度热图,因为这将 * 两个 * 变量的密度捕获为平滑函数。我正在寻找的是这样的东西,它将结果变量的分布的“切片”覆盖在散点图上:
的数据
我能想到的最好的办法是:
#### Load Library ####
library(tidyverse)
#### Get IQR ####
q <- quantile(iris$Sepal.Length,
probs = c(.25,.5,.75))
q
#### Label Quantile Regions ####
qiris <- iris %>%
mutate(qs = ifelse(Sepal.Length >= q[3],
"Q75",
ifelse(Sepal.Length >= q[2],
"Q50","Q25")))
#### Plot Density and Scatter ####
ggplot()+
geom_point(aes(x=Sepal.Width,
y=Sepal.Length),
data=iris)+
geom_density(aes(y=Sepal.Length,
fill=qs),
data=qiris)
字符串
但可以预见的是,这是失败的,因为它没有将分布的“切片”与预测值相关联。
的
然后我想出了一个稍微好一点的解决方案,可以正确定位值的分布:
library(ggridges)
ggplot(qiris,
aes(x = Sepal.Length,
y = qs)) +
stat_density_ridges(quantiles = c(0.25,0.5,0.75),
geom="density_ridges_gradient",
jittered_points = TRUE,
position = "raincloud",
alpha = 0.6,
scale = 0.6)+
coord_flip()
型
这给了我这个:
的
然而,这里仍然有三个问题。首先,我不能通过它拟合回归线。第二,我希望数据点像普通散点图一样彼此相邻,而不是通过分位数在空间上分开,这样它们就太远了。第三,这根本不包括其他变量,这很重要。
编辑
艾伦的答案一开始看起来不错,但我认为他的代码中有一些我没有看到的东西。为了弄清楚这一点,我尝试使用另一个数据集,并将输入保存为R中的对象,以便更容易交换所有内容。当我这样做时,我在图上得到了平坦的线条。
#### Load Library ####
library(tidyverse)
#### Save Objects ####
dfy <- mtcars$mpg # y var
dfx <- mtcars$hp # x var
data <- mtcars # dataset
#### QDATA ####
qdata <- data %>%
mutate(cut_group = cut(dfy,
quantile(dfy, c(0.125, 0.375, 0.625, 0.875)),
labels = c('Q25', 'Q50', 'Q75')),
baseline = quantile(dfy,
c(0.25, 0.5, 0.75))[as.numeric(cut_group)]) %>%
filter(complete.cases(.)) %>%
group_by(cut_group) %>%
reframe(dfxx = density(dfx)$x,
dfy = first(baseline) - density(dfx, bw = 0.5)$y/3) %>%
rename(dfx = dfxx)
ggplot(data,
aes(dfy,
dfx)) +
geom_smooth(method = 'lm',
color = 'gray',
se = FALSE) +
geom_point(color = 'navy',
shape = 21,
fill = NA) +
geom_path(data = qdata,
aes(group = cut_group),
color = 'darkgreen',
linewidth = 1.5) +
theme_classic() +
theme(panel.border = element_rect(fill = NA,
linewidth = 1))
型
就像这样:
1条答案
按热度按时间cuxqih211#
我可能会通过预先计算分位数的密度并将它们绘制为
geom_path
来做到这一点:字符串
的数据
对于
mtcars
示例,您需要为密度选择不同的带宽和乘数,以使其与现有变量大致相同:型
的