在R中绘制双变量到多个因素
Plotting a bivariate to multiple factors in R
首先,我还是个初学者。我正在尝试用 R 解释和绘制堆栈条形图。我已经看过一些答案,但有些不是我的案例所特有的,有些我根本不明白:
- https://stats.stackexchange.com/questions/31597/graphing-a-probability-curve-for-a-logit-model-with-multiple-predictors
- https://stats.stackexchange.com/questions/47020/plotting-logistic-regression-interaction-categorical-in-r
- Plot the results of a multivariate logistic regression model in R
我有一个数据集 dvl
,它有五列,Variant、Region、Time、Person 和 PrecededByPrep。我想对 Variant 与其他四个预测变量进行多变量比较。每列可以有两个可能值之一:
- 变体:
elk
或 ieder
。
- 地区 =
VL
或 NL
.
- 时间:
time
或 no time
- 人:
person
或 no person
- PrecededByPrep:
1
或 0
这是逻辑回归
根据我收集到的答案,库 ggplot2
可能是最好的绘图库。我已经阅读了它的文档,但对于我的生活,我无法弄清楚如何绘制它:我怎样才能将 Variant
与其他三个因素进行比较?
我花了一些时间,但我在 Photoshop 中制作了一些与我想要的相似的东西(虚构的值!)。
深色 gray/light 灰色:Variant
的可能值
y-axis:频率
x-axis:每一列,细分为可能的值
我知道制作单独的条形图,both stacked and grouped,但基本上我不知道如何制作堆叠的、分组的条形图。 ggplot2
可以使用,但如果没有我更愿意这样做。
我认为这可以看作是一个示例数据集,但我并不完全确定。我是 R 的初学者,我阅读了有关创建示例集的内容。
t <- data.frame(Variant = sample(c("iedere","elke"),size = 50, replace = TRUE),
Region = sample(c("VL","NL"),size = 50, replace = TRUE),
PrecededByPrep = sample(c("1","0"),size = 50, replace = TRUE),
Person = sample(c("person","no person"),size = 50, replace = TRUE),
Time = sample(c("time","no time"),size = 50, replace = TRUE))
我希望情节也能在美学上令人愉悦。我的想法是:
- 绘图颜色(即条形图):
col=c("paleturquoise3", "palegreen3")
- 轴标签
font.lab=2
的粗体字体,但 不是 的值标签(例如 ´regionin bold, but
VLand
NL`不是粗体)
#404040
作为字体、轴和线条的颜色
- 轴的标签:x:
factors
,y:frequency
这是一种可能性,它从 'un-tabulated' 数据框开始,melt
它,在 ggplot2
中用 geom_bar
绘制它(每组计数) , 使用 facet_wrap
.
按变量分隔图
创建玩具数据:
set.seed(123)
df <- data.frame(Variant = sample(c("iedere", "elke"), size = 50, replace = TRUE),
Region = sample(c("VL", "NL"), size = 50, replace = TRUE),
PrecededByPrep = sample(c("1", "0"), size = 50, replace = TRUE),
Person = sample(c("person", "no person"), size = 50, replace = TRUE),
Time = sample(c("time", "no time"), size = 50, replace = TRUE))
重塑数据:
library(reshape2)
df2 <- melt(df, id.vars = "Variant")
剧情:
library(ggplot2)
ggplot(data = df2, aes(factor(value), fill = Variant)) +
geom_bar() +
facet_wrap(~variable, nrow = 1, scales = "free_x") +
scale_fill_grey(start = 0.5) +
theme_bw()
自定义剧情的机会很多,比如setting order of factor levels, rotating axis labels, wrapping facet labels on two lines (e.g. for the longer variable name "PrecededByPrep"), or changing spacing between facets。
自定义(根据问题更新和 OP 评论)
# labeller function used in facet_grid to wrap "PrecededByPrep" on two lines
# see http://www.cookbook-r.com/Graphs/Facets_%28ggplot2%29/#modifying-facet-label-text
my_lab <- function(var, value){
value <- as.character(value)
if (var == "variable") {
ifelse(value == "PrecededByPrep", "Preceded\nByPrep", value)
}
}
ggplot(data = df2, aes(factor(value), fill = Variant)) +
geom_bar() +
facet_grid(~variable, scales = "free_x", labeller = my_lab) +
scale_fill_manual(values = c("paleturquoise3", "palegreen3")) + # manual fill colors
theme_bw() +
theme(axis.text = element_text(face = "bold"), # axis tick labels bold
axis.text.x = element_text(angle = 45, hjust = 1), # rotate x axis labels
line = element_line(colour = "gray25"), # line colour gray25 = #404040
strip.text = element_text(face = "bold")) + # facet labels bold
xlab("factors") + # set axis labels
ylab("frequency")
向每个条添加计数(根据 OP 的评论进行编辑)。
计算y坐标的基本原理可以在this Q&A中找到。在这里,我使用 dplyr
来计算每条柱的计数(即 geom_text
中的 label
)及其 y
坐标,但这当然可以在 base
R 中完成, plyr
或 data.table
。
# calculate counts (i.e. labels for geom_text) and their y positions.
library(dplyr)
df3 <- df2 %>%
group_by(variable, value, Variant) %>%
summarise(n = n()) %>%
mutate(y = cumsum(n) - (0.5 * n))
# plot
ggplot(data = df2, aes(x = factor(value), fill = Variant)) +
geom_bar() +
geom_text(data = df3, aes(y = y, label = n)) +
facet_grid(~variable, scales = "free_x", labeller = my_lab) +
scale_fill_manual(values = c("paleturquoise3", "palegreen3")) + # manual fill colors
theme_bw() +
theme(axis.text = element_text(face = "bold"), # axis tick labels bold
axis.text.x = element_text(angle = 45, hjust = 1), # rotate x axis labels
line = element_line(colour = "gray25"), # line colour gray25 = #404040
strip.text = element_text(face = "bold")) + # facet labels bold
xlab("factors") + # set axis labels
ylab("frequency")
这是我对基数 R 的函数 barplot
的解决方案的建议:
1.计算计数
l_count_df<-lapply(colnames(t)[-1],function(nomcol){table(t$Variant,t[,nomcol])})
count_df<-l_count_df[[1]]
for (i in 2:length(l_count_df)){
count_df<-cbind(count_df,l_count_df[[i]])
}
2。绘制没有轴名称的条形图,保存条形坐标
par(las=1,col.axis="#404040",mar=c(5,4.5,4,2),mgp=c(3.5,1,0))
bp<-barplot(count_df,width=1.2,space=rep(c(1,0.3),4),col=c("paleturquoise3", "palegreen3"),border="#404040", axisname=F, ylab="Frequency",
legend=row.names(count_df),ylim=c(0,max(colSums(count_df))*1.2))
3。标记条形
mtext(side=1,line=0.8,at=bp,text=colnames(count_df))
mtext(side=1,line=2,at=(bp[seq(1,8,by=2)]+bp[seq(2,8,by=2)])/2,text=colnames(t)[-1],font=2)
4.在 bars
内添加值
for(i in 1:ncol(count_df)){
val_elke<-count_df[1,i]
val_iedere<-count_df[2,i]
text(bp[i],val_elke/2,val_elke)
text(bp[i],val_elke+val_iedere/2,val_iedere)
}
这是我得到的(使用我的随机数据):
我基本上是在回答一个不同的问题。我想这可以被视为我的反常行为,但我真的不喜欢任何类型的条形图。它们似乎总是造成浪费 space,因为当前信息化的数值不如适当构建的 table 有用。 vcd
包提供了一个扩展的 mosaicplot 函数,在我看来,它更准确地称为“多元条形图”,它是我迄今为止所见过的任何一个。它确实需要你首先构建一个意外事件 table xtabs
函数似乎非常适合。
install.packages)"vcd")
library(vcd)
help(package=vcd,mosaic)
col=c("paleturquoise3", "palegreen3")
vcd::mosaic(xtabs(~Variant+Region + PrecededByPrep + Time, data=ttt)
,highlighting="Variant", highlighting_fill=col)
那是 5 路图,这是 5 路图:
png(); vcd::mosaic( xtabs(
~Variant+Region + PrecededByPrep + Person + Time,
data=ttt)
,highlighting="Variant", highlighting_fill=col); dev.off()
首先,我还是个初学者。我正在尝试用 R 解释和绘制堆栈条形图。我已经看过一些答案,但有些不是我的案例所特有的,有些我根本不明白:
- https://stats.stackexchange.com/questions/31597/graphing-a-probability-curve-for-a-logit-model-with-multiple-predictors
- https://stats.stackexchange.com/questions/47020/plotting-logistic-regression-interaction-categorical-in-r
- Plot the results of a multivariate logistic regression model in R
我有一个数据集 dvl
,它有五列,Variant、Region、Time、Person 和 PrecededByPrep。我想对 Variant 与其他四个预测变量进行多变量比较。每列可以有两个可能值之一:
- 变体:
elk
或ieder
。 - 地区 =
VL
或NL
. - 时间:
time
或no time
- 人:
person
或no person
- PrecededByPrep:
1
或0
这是逻辑回归
根据我收集到的答案,库 ggplot2
可能是最好的绘图库。我已经阅读了它的文档,但对于我的生活,我无法弄清楚如何绘制它:我怎样才能将 Variant
与其他三个因素进行比较?
我花了一些时间,但我在 Photoshop 中制作了一些与我想要的相似的东西(虚构的值!)。
深色 gray/light 灰色:Variant
的可能值
y-axis:频率
x-axis:每一列,细分为可能的值
我知道制作单独的条形图,both stacked and grouped,但基本上我不知道如何制作堆叠的、分组的条形图。 ggplot2
可以使用,但如果没有我更愿意这样做。
我认为这可以看作是一个示例数据集,但我并不完全确定。我是 R 的初学者,我阅读了有关创建示例集的内容。
t <- data.frame(Variant = sample(c("iedere","elke"),size = 50, replace = TRUE),
Region = sample(c("VL","NL"),size = 50, replace = TRUE),
PrecededByPrep = sample(c("1","0"),size = 50, replace = TRUE),
Person = sample(c("person","no person"),size = 50, replace = TRUE),
Time = sample(c("time","no time"),size = 50, replace = TRUE))
我希望情节也能在美学上令人愉悦。我的想法是:
- 绘图颜色(即条形图):
col=c("paleturquoise3", "palegreen3")
- 轴标签
font.lab=2
的粗体字体,但 不是 的值标签(例如 ´regionin bold, but
VLand
NL`不是粗体) #404040
作为字体、轴和线条的颜色- 轴的标签:x:
factors
,y:frequency
这是一种可能性,它从 'un-tabulated' 数据框开始,melt
它,在 ggplot2
中用 geom_bar
绘制它(每组计数) , 使用 facet_wrap
.
创建玩具数据:
set.seed(123)
df <- data.frame(Variant = sample(c("iedere", "elke"), size = 50, replace = TRUE),
Region = sample(c("VL", "NL"), size = 50, replace = TRUE),
PrecededByPrep = sample(c("1", "0"), size = 50, replace = TRUE),
Person = sample(c("person", "no person"), size = 50, replace = TRUE),
Time = sample(c("time", "no time"), size = 50, replace = TRUE))
重塑数据:
library(reshape2)
df2 <- melt(df, id.vars = "Variant")
剧情:
library(ggplot2)
ggplot(data = df2, aes(factor(value), fill = Variant)) +
geom_bar() +
facet_wrap(~variable, nrow = 1, scales = "free_x") +
scale_fill_grey(start = 0.5) +
theme_bw()
自定义剧情的机会很多,比如setting order of factor levels, rotating axis labels, wrapping facet labels on two lines (e.g. for the longer variable name "PrecededByPrep"), or changing spacing between facets。
自定义(根据问题更新和 OP 评论)
# labeller function used in facet_grid to wrap "PrecededByPrep" on two lines
# see http://www.cookbook-r.com/Graphs/Facets_%28ggplot2%29/#modifying-facet-label-text
my_lab <- function(var, value){
value <- as.character(value)
if (var == "variable") {
ifelse(value == "PrecededByPrep", "Preceded\nByPrep", value)
}
}
ggplot(data = df2, aes(factor(value), fill = Variant)) +
geom_bar() +
facet_grid(~variable, scales = "free_x", labeller = my_lab) +
scale_fill_manual(values = c("paleturquoise3", "palegreen3")) + # manual fill colors
theme_bw() +
theme(axis.text = element_text(face = "bold"), # axis tick labels bold
axis.text.x = element_text(angle = 45, hjust = 1), # rotate x axis labels
line = element_line(colour = "gray25"), # line colour gray25 = #404040
strip.text = element_text(face = "bold")) + # facet labels bold
xlab("factors") + # set axis labels
ylab("frequency")
向每个条添加计数(根据 OP 的评论进行编辑)。
计算y坐标的基本原理可以在this Q&A中找到。在这里,我使用 dplyr
来计算每条柱的计数(即 geom_text
中的 label
)及其 y
坐标,但这当然可以在 base
R 中完成, plyr
或 data.table
。
# calculate counts (i.e. labels for geom_text) and their y positions.
library(dplyr)
df3 <- df2 %>%
group_by(variable, value, Variant) %>%
summarise(n = n()) %>%
mutate(y = cumsum(n) - (0.5 * n))
# plot
ggplot(data = df2, aes(x = factor(value), fill = Variant)) +
geom_bar() +
geom_text(data = df3, aes(y = y, label = n)) +
facet_grid(~variable, scales = "free_x", labeller = my_lab) +
scale_fill_manual(values = c("paleturquoise3", "palegreen3")) + # manual fill colors
theme_bw() +
theme(axis.text = element_text(face = "bold"), # axis tick labels bold
axis.text.x = element_text(angle = 45, hjust = 1), # rotate x axis labels
line = element_line(colour = "gray25"), # line colour gray25 = #404040
strip.text = element_text(face = "bold")) + # facet labels bold
xlab("factors") + # set axis labels
ylab("frequency")
这是我对基数 R 的函数 barplot
的解决方案的建议:
1.计算计数
l_count_df<-lapply(colnames(t)[-1],function(nomcol){table(t$Variant,t[,nomcol])})
count_df<-l_count_df[[1]]
for (i in 2:length(l_count_df)){
count_df<-cbind(count_df,l_count_df[[i]])
}
2。绘制没有轴名称的条形图,保存条形坐标
par(las=1,col.axis="#404040",mar=c(5,4.5,4,2),mgp=c(3.5,1,0))
bp<-barplot(count_df,width=1.2,space=rep(c(1,0.3),4),col=c("paleturquoise3", "palegreen3"),border="#404040", axisname=F, ylab="Frequency",
legend=row.names(count_df),ylim=c(0,max(colSums(count_df))*1.2))
3。标记条形
mtext(side=1,line=0.8,at=bp,text=colnames(count_df))
mtext(side=1,line=2,at=(bp[seq(1,8,by=2)]+bp[seq(2,8,by=2)])/2,text=colnames(t)[-1],font=2)
4.在 bars
内添加值for(i in 1:ncol(count_df)){
val_elke<-count_df[1,i]
val_iedere<-count_df[2,i]
text(bp[i],val_elke/2,val_elke)
text(bp[i],val_elke+val_iedere/2,val_iedere)
}
这是我得到的(使用我的随机数据):
我基本上是在回答一个不同的问题。我想这可以被视为我的反常行为,但我真的不喜欢任何类型的条形图。它们似乎总是造成浪费 space,因为当前信息化的数值不如适当构建的 table 有用。 vcd
包提供了一个扩展的 mosaicplot 函数,在我看来,它更准确地称为“多元条形图”,它是我迄今为止所见过的任何一个。它确实需要你首先构建一个意外事件 table xtabs
函数似乎非常适合。
install.packages)"vcd")
library(vcd)
help(package=vcd,mosaic)
col=c("paleturquoise3", "palegreen3")
vcd::mosaic(xtabs(~Variant+Region + PrecededByPrep + Time, data=ttt)
,highlighting="Variant", highlighting_fill=col)
那是 5 路图,这是 5 路图:
png(); vcd::mosaic( xtabs(
~Variant+Region + PrecededByPrep + Person + Time,
data=ttt)
,highlighting="Variant", highlighting_fill=col); dev.off()