使用 ggplot 绘制两条重叠的密度曲线
Plotting two overlapping density curves using ggplot
我在 R 中有一个包含 104 列的数据框,显示如下:
id vcr1 vcr2 vcr3 sim_vcr1 sim_vcr2 sim_vcr3 sim_vcr4 sim_vcr5 sim_vcr6 sim_vcr7
1 2913 -4.782992840 1.7631999 0.003768704 1.376937 -2.096857 6.903021 7.018855 6.135139 3.188382 6.905323
2 1260 0.003768704 3.1577108 -0.758378208 1.376937 -2.096857 6.903021 7.018855 6.135139 3.188382 6.905323
3 2912 -4.782992840 1.7631999 0.003768704 1.376937 -2.096857 6.903021 7.018855 6.135139 3.188382 6.905323
4 2914 -1.311132669 0.8220594 2.372950077 -4.194246 -1.460474 -9.101704 -6.663676 -5.364724 -2.717272 -3.682574
5 2915 -1.311132669 0.8220594 2.372950077 -4.194246 -1.460474 -9.101704 -6.663676 -5.364724 -2.717272 -3.682574
6 1261 2.372950077 -0.7022792 -4.951318264 -4.194246 -1.460474 -9.101704 -6.663676 -5.364724 -2.717272 -3.682574
“sim_vcr*”变量一直到 sim_vcr100
我需要在一个图中包含两条重叠的密度密度曲线,看起来像这样(除了这里你看到的是 5 而不是 2):
我需要一条密度曲线包含列 vcr1、vcr2 和 vcr3 中包含的所有值,我需要另一条密度曲线包含所有 sim_vcr* 列中的所有值(因此 100列,sim_vcr1-sim_vcr100)
因为两条曲线重叠,所以它们需要是透明的,如附图所示。我知道有一种非常简单的方法可以使用 ggplot
命令来执行此操作,但我在语法方面遇到了问题,并且无法正确定位数据框,以便每个直方图都来自正确的列。
非常感谢任何帮助。
df
是您在 post 中提到的数据,您可以试试这个:
用下一个代码分离数据帧,然后绘图:
library(tidyverse)
library(gdata)
#Index
i1 <- which(startsWith(names(df),pattern = 'vcr'))
i2 <- which(startsWith(names(df),pattern = 'sim'))
#Isolate
df1 <- df[,c(1,i1)]
df2 <- df[,c(1,i2)]
#Melt
M1 <- pivot_longer(df1,cols = names(df1)[-1])
M2 <- pivot_longer(df2,cols = names(df2)[-1])
#Plot 1
ggplot(M1) + geom_density(aes(x=value,fill=name), alpha=.5)
#Plot 2
ggplot(M2) + geom_density(aes(x=value,fill=name), alpha=.5)
更新
对一个图使用下一个代码:
#Unique plot
#Melt
M <- pivot_longer(df,cols = names(df)[-1])
#Mutate
M$var <- ifelse(startsWith(M$name,'vcr',),'vcr','sim_vcr')
#Plot 3
ggplot(M) + geom_density(aes(x=value,fill=var), alpha=.5)
使用 dplyr
包,首先您可以使用函数 pivot_longer
将数据转换为长格式,如下所示:
df %<>% pivot_longer(cols = c(starts_with('vcr'), starts_with('sim_vcr')),
names_to = c('type'),
values_to = c('values'))
使用 filter
函数后,您可以为每个值类型创建单独的图
对于 vcr
列:
df %>%
filter(str_detect(type, '^vcr')) %>%
ggplot(.) +
geom_density(aes(x = values, fill = type), alpha = 0.5)
以上产生了以下情节:
对于 sim_vcr
列:
df %>%
filter(str_detect(type, '^sim_vcr')) %>%
ggplot(.) +
geom_density(aes(x = values, fill = type), alpha = 0.5)
以上代码产生了以下情节:
另一种为 ggplot 子集和准备数据的简单方法是使用 tidyr 的 gather(),您可以阅读更多相关信息。我是这样做的。 df 是您提供的数据框。
# Load tidyr to use gather()
library(tidyr)
#Split appart the data you dont want on their own, the first three columns, and gather them
df_vcr <- gather(data = df[,2:4])
#Gather the other columns in the dataframe
df_sim<- gather(data = df[,-c(1:4)])
#Plot the first
ggplot() +
geom_density(data = df_vcr,
mapping = aes(value, group = key, color = key, fill = key),
alpha = 0.5)
#Plot the second
ggplot() +
geom_density(data = df_sim,
mapping = aes(value, group = key, color = key, fill = key),
alpha = 0.5)
不过,我不太清楚您所说的“所有 sim_vcr* 列中的所有值”是什么意思。也许您希望所有这些值都在一条密度曲线中?要做到这一点,在第二种情况下不要给 ggplot 任何分组信息。
ggplot() + geom_density(data = df_sim,
mapping = aes(value),
fill = "grey50",
alpha = 0.5)
请注意,我仍然可以在 aes() 函数之外为曲线指定 'fill',它会将它应用于所有曲线,而不是为 'key' 中指定的每个组指定不同的颜色.
我在 R 中有一个包含 104 列的数据框,显示如下:
id vcr1 vcr2 vcr3 sim_vcr1 sim_vcr2 sim_vcr3 sim_vcr4 sim_vcr5 sim_vcr6 sim_vcr7
1 2913 -4.782992840 1.7631999 0.003768704 1.376937 -2.096857 6.903021 7.018855 6.135139 3.188382 6.905323
2 1260 0.003768704 3.1577108 -0.758378208 1.376937 -2.096857 6.903021 7.018855 6.135139 3.188382 6.905323
3 2912 -4.782992840 1.7631999 0.003768704 1.376937 -2.096857 6.903021 7.018855 6.135139 3.188382 6.905323
4 2914 -1.311132669 0.8220594 2.372950077 -4.194246 -1.460474 -9.101704 -6.663676 -5.364724 -2.717272 -3.682574
5 2915 -1.311132669 0.8220594 2.372950077 -4.194246 -1.460474 -9.101704 -6.663676 -5.364724 -2.717272 -3.682574
6 1261 2.372950077 -0.7022792 -4.951318264 -4.194246 -1.460474 -9.101704 -6.663676 -5.364724 -2.717272 -3.682574
“sim_vcr*”变量一直到 sim_vcr100
我需要在一个图中包含两条重叠的密度密度曲线,看起来像这样(除了这里你看到的是 5 而不是 2):
我需要一条密度曲线包含列 vcr1、vcr2 和 vcr3 中包含的所有值,我需要另一条密度曲线包含所有 sim_vcr* 列中的所有值(因此 100列,sim_vcr1-sim_vcr100)
因为两条曲线重叠,所以它们需要是透明的,如附图所示。我知道有一种非常简单的方法可以使用 ggplot
命令来执行此操作,但我在语法方面遇到了问题,并且无法正确定位数据框,以便每个直方图都来自正确的列。
非常感谢任何帮助。
df
是您在 post 中提到的数据,您可以试试这个:
用下一个代码分离数据帧,然后绘图:
library(tidyverse)
library(gdata)
#Index
i1 <- which(startsWith(names(df),pattern = 'vcr'))
i2 <- which(startsWith(names(df),pattern = 'sim'))
#Isolate
df1 <- df[,c(1,i1)]
df2 <- df[,c(1,i2)]
#Melt
M1 <- pivot_longer(df1,cols = names(df1)[-1])
M2 <- pivot_longer(df2,cols = names(df2)[-1])
#Plot 1
ggplot(M1) + geom_density(aes(x=value,fill=name), alpha=.5)
#Plot 2
ggplot(M2) + geom_density(aes(x=value,fill=name), alpha=.5)
更新
对一个图使用下一个代码:
#Unique plot
#Melt
M <- pivot_longer(df,cols = names(df)[-1])
#Mutate
M$var <- ifelse(startsWith(M$name,'vcr',),'vcr','sim_vcr')
#Plot 3
ggplot(M) + geom_density(aes(x=value,fill=var), alpha=.5)
使用 dplyr
包,首先您可以使用函数 pivot_longer
将数据转换为长格式,如下所示:
df %<>% pivot_longer(cols = c(starts_with('vcr'), starts_with('sim_vcr')),
names_to = c('type'),
values_to = c('values'))
使用 filter
函数后,您可以为每个值类型创建单独的图
对于 vcr
列:
df %>%
filter(str_detect(type, '^vcr')) %>%
ggplot(.) +
geom_density(aes(x = values, fill = type), alpha = 0.5)
以上产生了以下情节:
sim_vcr
列:
df %>%
filter(str_detect(type, '^sim_vcr')) %>%
ggplot(.) +
geom_density(aes(x = values, fill = type), alpha = 0.5)
以上代码产生了以下情节:
另一种为 ggplot 子集和准备数据的简单方法是使用 tidyr 的 gather(),您可以阅读更多相关信息。我是这样做的。 df 是您提供的数据框。
# Load tidyr to use gather()
library(tidyr)
#Split appart the data you dont want on their own, the first three columns, and gather them
df_vcr <- gather(data = df[,2:4])
#Gather the other columns in the dataframe
df_sim<- gather(data = df[,-c(1:4)])
#Plot the first
ggplot() +
geom_density(data = df_vcr,
mapping = aes(value, group = key, color = key, fill = key),
alpha = 0.5)
#Plot the second
ggplot() +
geom_density(data = df_sim,
mapping = aes(value, group = key, color = key, fill = key),
alpha = 0.5)
不过,我不太清楚您所说的“所有 sim_vcr* 列中的所有值”是什么意思。也许您希望所有这些值都在一条密度曲线中?要做到这一点,在第二种情况下不要给 ggplot 任何分组信息。
ggplot() + geom_density(data = df_sim,
mapping = aes(value),
fill = "grey50",
alpha = 0.5)
请注意,我仍然可以在 aes() 函数之外为曲线指定 'fill',它会将它应用于所有曲线,而不是为 'key' 中指定的每个组指定不同的颜色.