R:facet_grid 使用 ggplot2 绘制的组间差异图
R: facet_grid plot of differences between groups using ggplot2
我正在尝试创建一系列图表来显示测量变量组之间的差异,并且正在寻找一种有效的方法来使用 R 中 ggplot2
的 facet_grid
功能.
这是一个说明性的例子:
# sample input data
df <- data.frame(year=rep(c(2011:2015), 2),
value=c(0:4, 1:5),
scenario=rep(c("a","b"), each=5))
# make a sample plot
p <-
ggplot(df, aes(x=year, y=value)) +
geom_point() + geom_line() +
facet_grid(scenario ~ scenario)
这会生成以下示例图,其中针对每个场景组合分别针对 value
绘制 year
:
(我假设没有绘制第二行,因为它与第一行相同)。
但是,我正在寻找的是一个图,其中在每个方面,(顶部方案中的值)-(右侧方案中的值)按年份绘制。具体来说:
- 所有年份的左上图均为(值 a)-(值 a)= 0。
- 所有年份的右上图均为(值 b)-(值 a)= 1。
- 对于所有年份,左下图为(值 a)-(值 b)= -1。
- 所有年份的右下图都是(值 b)-(值 b)= 0
我无法找到 facet_grid
的任何内置或自动差异命令。我最初的想法是将函数作为 y
参数传递给 ggplot
,但考虑到数据框只有一个 value
列,我被难住了。我猜可能有一个使用 dplyr
和 reshape2
的某种组合的解决方案,但我无法理解如何实现它。
这是一个选项,它使用 tidyr
中的一些函数,首先 spread
计算数据以计算对比度,然后 gather
将其组合在一起以允许绘图:
forPlotting <-
df %>%
spread(scenario, value) %>%
mutate(`a - b` = a - b
, `b - a` = b - a
, `a - a` = 0
, `b - b` = 0) %>%
gather(Comparison, Difference, -(year:b) ) %>%
separate(Comparison, c("First Val", "Second Val"), " - ")
那个returns一个data.frame像这样(这里只是头):
year a b First Val Second Val Difference
1 2011 0 1 a b -1
2 2012 1 2 a b -1
3 2013 2 3 a b -1
4 2014 3 4 a b -1
5 2015 4 5 a b -1
6 2011 0 1 b a 1
你可以这样画:
ggplot(forPlotting
, aes(x = year, y = Difference)) +
geom_point() + geom_line() +
facet_grid(`First Val` ~ `Second Val`)
更大的问题是为什么你想这样做。我假设您已经知道将两组绘制成不同颜色的线条更容易可视化:
ggplot(df, aes(x=year, y=value, col = scenario)) +
geom_point() + geom_line()
所以,我假设您有更复杂的数据——具体来说,有更多的列要比较。因此,这里有一种方法可以自动化(并简化)多个列的上述许多步骤。方法基本相同,但它使用 mutate_
允许您传入一个包含您要创建的列的向量。
df <-
data.frame(
year = 2011:2015
, a = 0:4
, b = 1:5
, c = 2:6
, d = 3:7
)
allContrasts <-
outer(colnames(df)[-1]
, colnames(df)[-1]
, paste
, sep = " - ") %>%
as.character() %>%
setNames(., .) %>%
as.list()
forPlotting <-
df %>%
mutate_(.dots = allContrasts) %>%
select(-(a:d)) %>%
gather(Comparison, Difference, -year ) %>%
separate(Comparison, c("First Val", "Second Val"), " - ") %>%
filter(`First Val` != `Second Val`)
ggplot(forPlotting
, aes(x = year, y = Difference)) +
geom_point() + geom_line() +
facet_grid(`First Val` ~ `Second Val`) +
theme(axis.text.x = element_text(angle = 90))
给出这个:
为什么我不能不管这个?我就是太喜欢玩标准评价了。如果您有非解析列名(例如,带空格的东西),上述将失败。因此,这是一个包含此类列名的示例,显示了添加反引号以确保列正确解析。
df <-
data.frame(
year = 2011:2015
, value = c(0:4, 1:5, 2:6, 3:7)
, scenario = rep(c("Unit 1", "Exam 2"
, "Homework", "Final Exam")
, each = 5)
) %>%
spread(scenario, value)
allContrasts <-
outer(paste0("`", colnames(df)[-1], "`")
, paste0("`", colnames(df)[-1], "`")
, paste
, sep = " - ") %>%
as.character() %>%
setNames(., .) %>%
as.list()
forPlotting <-
df %>%
mutate_(.dots = allContrasts) %>%
select_(.dots = paste0("-`", colnames(df)[-1], "`")) %>%
gather(Comparison, Difference, -year ) %>%
separate(Comparison, c("First Val", "Second Val"), " - ") %>%
filter(`First Val` != `Second Val`) %>%
mutate_each(funs(gsub("`", "", .)), `First Val`, `Second Val`)
ggplot(forPlotting
, aes(x = year, y = Difference)) +
geom_point() + geom_line() +
facet_grid(`First Val` ~ `Second Val`) +
theme(axis.text.x = element_text(angle = 90))
你想要下面这样的东西吗?
dflist <- split(df, df$scenario)
df <- rbind(merge(dflist$a, dflist$a, by='year'),
merge(dflist$a, dflist$b, by='year'),
merge(dflist$b, dflist$a, by='year'),
merge(dflist$b, dflist$b, by='year'))
df$value <- df$value.x - df$value.y
ggplot(df, aes(x=year, y=value)) +
geom_point() + geom_line() +
facet_grid(scenario.x ~ scenario.y)
我正在尝试创建一系列图表来显示测量变量组之间的差异,并且正在寻找一种有效的方法来使用 R 中 ggplot2
的 facet_grid
功能.
这是一个说明性的例子:
# sample input data
df <- data.frame(year=rep(c(2011:2015), 2),
value=c(0:4, 1:5),
scenario=rep(c("a","b"), each=5))
# make a sample plot
p <-
ggplot(df, aes(x=year, y=value)) +
geom_point() + geom_line() +
facet_grid(scenario ~ scenario)
这会生成以下示例图,其中针对每个场景组合分别针对 value
绘制 year
:
(我假设没有绘制第二行,因为它与第一行相同)。
但是,我正在寻找的是一个图,其中在每个方面,(顶部方案中的值)-(右侧方案中的值)按年份绘制。具体来说:
- 所有年份的左上图均为(值 a)-(值 a)= 0。
- 所有年份的右上图均为(值 b)-(值 a)= 1。
- 对于所有年份,左下图为(值 a)-(值 b)= -1。
- 所有年份的右下图都是(值 b)-(值 b)= 0
我无法找到 facet_grid
的任何内置或自动差异命令。我最初的想法是将函数作为 y
参数传递给 ggplot
,但考虑到数据框只有一个 value
列,我被难住了。我猜可能有一个使用 dplyr
和 reshape2
的某种组合的解决方案,但我无法理解如何实现它。
这是一个选项,它使用 tidyr
中的一些函数,首先 spread
计算数据以计算对比度,然后 gather
将其组合在一起以允许绘图:
forPlotting <-
df %>%
spread(scenario, value) %>%
mutate(`a - b` = a - b
, `b - a` = b - a
, `a - a` = 0
, `b - b` = 0) %>%
gather(Comparison, Difference, -(year:b) ) %>%
separate(Comparison, c("First Val", "Second Val"), " - ")
那个returns一个data.frame像这样(这里只是头):
year a b First Val Second Val Difference
1 2011 0 1 a b -1
2 2012 1 2 a b -1
3 2013 2 3 a b -1
4 2014 3 4 a b -1
5 2015 4 5 a b -1
6 2011 0 1 b a 1
你可以这样画:
ggplot(forPlotting
, aes(x = year, y = Difference)) +
geom_point() + geom_line() +
facet_grid(`First Val` ~ `Second Val`)
更大的问题是为什么你想这样做。我假设您已经知道将两组绘制成不同颜色的线条更容易可视化:
ggplot(df, aes(x=year, y=value, col = scenario)) +
geom_point() + geom_line()
所以,我假设您有更复杂的数据——具体来说,有更多的列要比较。因此,这里有一种方法可以自动化(并简化)多个列的上述许多步骤。方法基本相同,但它使用 mutate_
允许您传入一个包含您要创建的列的向量。
df <-
data.frame(
year = 2011:2015
, a = 0:4
, b = 1:5
, c = 2:6
, d = 3:7
)
allContrasts <-
outer(colnames(df)[-1]
, colnames(df)[-1]
, paste
, sep = " - ") %>%
as.character() %>%
setNames(., .) %>%
as.list()
forPlotting <-
df %>%
mutate_(.dots = allContrasts) %>%
select(-(a:d)) %>%
gather(Comparison, Difference, -year ) %>%
separate(Comparison, c("First Val", "Second Val"), " - ") %>%
filter(`First Val` != `Second Val`)
ggplot(forPlotting
, aes(x = year, y = Difference)) +
geom_point() + geom_line() +
facet_grid(`First Val` ~ `Second Val`) +
theme(axis.text.x = element_text(angle = 90))
给出这个:
为什么我不能不管这个?我就是太喜欢玩标准评价了。如果您有非解析列名(例如,带空格的东西),上述将失败。因此,这是一个包含此类列名的示例,显示了添加反引号以确保列正确解析。
df <-
data.frame(
year = 2011:2015
, value = c(0:4, 1:5, 2:6, 3:7)
, scenario = rep(c("Unit 1", "Exam 2"
, "Homework", "Final Exam")
, each = 5)
) %>%
spread(scenario, value)
allContrasts <-
outer(paste0("`", colnames(df)[-1], "`")
, paste0("`", colnames(df)[-1], "`")
, paste
, sep = " - ") %>%
as.character() %>%
setNames(., .) %>%
as.list()
forPlotting <-
df %>%
mutate_(.dots = allContrasts) %>%
select_(.dots = paste0("-`", colnames(df)[-1], "`")) %>%
gather(Comparison, Difference, -year ) %>%
separate(Comparison, c("First Val", "Second Val"), " - ") %>%
filter(`First Val` != `Second Val`) %>%
mutate_each(funs(gsub("`", "", .)), `First Val`, `Second Val`)
ggplot(forPlotting
, aes(x = year, y = Difference)) +
geom_point() + geom_line() +
facet_grid(`First Val` ~ `Second Val`) +
theme(axis.text.x = element_text(angle = 90))
你想要下面这样的东西吗?
dflist <- split(df, df$scenario)
df <- rbind(merge(dflist$a, dflist$a, by='year'),
merge(dflist$a, dflist$b, by='year'),
merge(dflist$b, dflist$a, by='year'),
merge(dflist$b, dflist$b, by='year'))
df$value <- df$value.x - df$value.y
ggplot(df, aes(x=year, y=value)) +
geom_point() + geom_line() +
facet_grid(scenario.x ~ scenario.y)