R:使用ggplot2

时间:2016-11-10 16:11:06

标签: r plot ggplot2 reshape facet

我尝试创建一系列图表,显示测量变量组之间的差异,并且正在使用R中facet_grid的{​​{1}}功能搜索有效的方法。

以下是一个说明性示例:

ggplot2

这将生成以下示例图,其中# 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绘制:

sample facet plot

(我假设没有绘制第二行,因为它与第一行相同)。

然而,我正在寻找的是一个情节,其中,在每个方面,(情景中的值) - (右侧情景中的值)按年绘制。具体做法是:

  • 左上图将是(值a) - (值a)= 0表示所有年份。
  • 右上图将是(值b) - (值a)= 1所有年份。
  • 左下图将是(值a) - (值b)= -1所有年份。
  • 右下图将是(值b) - (值b)= 0表示所有年份

我无法找到year的任何内置或自动差异命令。我最初的想法是将一个函数作为facet_grid参数传递给y,但鉴于数据框有一个ggplot列,我感到难过。我猜可能有一个使用valuedplyr的组合的解决方案,但无法解决如何实现它。

2 个答案:

答案 0 :(得分:2)

这是一个选项,使用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"), " - ")

返回一个像这样的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`)

enter image description here

更大的问题是为什么你想要这样做。我假设您已经知道只是将两组绘制为不同的颜色线是一种更容易的可视化:

ggplot(df, aes(x=year, y=value, col = scenario)) +
  geom_point() + geom_line()

enter image description here

所以,我假设你有更复杂的数据 - 具体来说,有更多的列要比较。因此,这里有一种方法可以自动化(并简化)多列上述许多步骤。该方法基本相同,但它使用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))

给出这个:

enter image description here

为什么我不能单独留下这个?我只是喜欢玩标准评估太多了。如果您有非解析列名称(例如带空格的内容),则上述操作将失败。所以,这里有一个这样的列名称的示例,显示添加反引号以确保列正确解析。

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))

enter image description here

答案 1 :(得分:1)

您想要以下内容吗?

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)

enter image description here