ggplot2:具有两个变量的多层图的facet_wrap失败

时间:2018-06-08 16:20:44

标签: r ggplot2

我正在尝试使用ggplot2创建一个包含自由缩放的多面图。按照设计,facet_grid无法实现我的需要。并且facet_wrap因错误的错误而失败。您能告诉我,您对如何解决错误有任何建议吗?下面给出了一个可重复的例子。

让我们创建样本数据:

require(tidyverse)
require(modelr)

d1 <- tibble(
  x = 1:100,
  y = 1:100 + rnorm(10),
  z = y ^ 2,
  dataset_name = "d1"
)

d2 <- tibble(
  x = 1:1000,
  y = 1:1000 + rnorm(10),
  z = y ^ 2,
  dataset_name = "d2"
)

#these data will be used for the 1st layer
actuals <- bind_rows(d1, d2)

#these data will be used for the 2nd layer
predictions <- bind_rows(
  d1 %>% gather_predictions(
    "m1" = lm(y ~ x, data = d1),
    "m2" = lm(y ~ x + z, data = d1),
    .pred = "y"
  ),
  d2 %>% gather_predictions(
    "m1" = lm(y ~ x, data = d2),
    "m2" = lm(y ~ x + z, data = d2),
    .pred = "y"
  )
)

facet_grid生成了必需的图表:

the figure

但它不能(按设计)缩放x轴:

ggplot(actuals, aes(x, y)) +
  geom_point() +
  geom_line(data = predictions, colour = "red") +
  facet_grid(dataset_name ~ model, scales = "free")

如果我只想为一个数据集绘制数据(即predictions),它会按预期工作,我会得到4个方面:

img

ggplot(predictions, aes(x, y)) +
  geom_point() +
  facet_wrap( ~ model + dataset_name, scales = "free")

但是,如果我尝试将actualspredictions合并如下:

ggplot(actuals, aes(x, y)) +
  geom_point() +
  geom_line(data = predictions, colour = "red") +
  facet_wrap( ~ model + dataset_name, scales = "free")

然后出现以下错误:Error in gList(list(x = 0.5, y = 0.5, width = 1, height = 1, just = "centre", : only 'grobs' allowed in "gList"

2 个答案:

答案 0 :(得分:2)

尝试使用modeldataset_name的互动制作单个变量。

# these two blocks of code are equivalent

library(magrittr)
predictions %<>% mutate(mod_dn = interaction(model, dataset_name))

predictions <- predictions %>% 
  mutate(mod_dn = interaction(model, dataset_name))

现在,这给facet_wrap带来了问题,因为那里不存在mod_dn。所以我们需要将两个数据集合并在一起。使用tidyverse,我们可以使用left_join执行此操作,但我们需要注意我们加入的内容,然后相应地调整ggplot调用:

all_data <- left_join(
  actuals,
  predictions,
  by = c("x", "dataset_name"),
  suffix = c(".actual", ".pred")
)

all_data %>%
ggplot(aes(x, y.actual)) +
  geom_point() +
  geom_line(aes(y = y.pred), colour = "red") +
  facet_wrap( ~ mod_dn, scales = "free") +
  labs(y = "y")

答案 1 :(得分:0)

谢谢大家的帮助!似乎更简单的解决方案(即使它会改变原始问题),将调整func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { // Stop scrolling targetContentOffset.pointee = scrollView.contentOffset // Calculate conditions let pageWidth = // The width your page should have (plus a possible margin) let collectionViewItemCount = // The number of items in this section let proportionalOffset = collectionView.contentOffset.x / pageWidth let indexOfMajorCell = Int(round(proportionalOffset)) let swipeVelocityThreshold: CGFloat = 0.5 let hasEnoughVelocityToSlideToTheNextCell = indexOfCellBeforeDragging + 1 < collectionViewItemCount && velocity.x > swipeVelocityThreshold let hasEnoughVelocityToSlideToThePreviousCell = indexOfCellBeforeDragging - 1 >= 0 && velocity.x < -swipeVelocityThreshold let majorCellIsTheCellBeforeDragging = indexOfMajorCell == indexOfCellBeforeDragging let didUseSwipeToSkipCell = majorCellIsTheCellBeforeDragging && (hasEnoughVelocityToSlideToTheNextCell || hasEnoughVelocityToSlideToThePreviousCell) if didUseSwipeToSkipCell { // Animate so that swipe is just continued let snapToIndex = indexOfCellBeforeDragging + (hasEnoughVelocityToSlideToTheNextCell ? 1 : -1) let toValue = pageWidth * CGFloat(snapToIndex) UIView.animate( withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: velocity.x, options: .allowUserInteraction, animations: { scrollView.contentOffset = CGPoint(x: toValue, y: 0) scrollView.layoutIfNeeded() }, completion: nil ) } else { // Pop back (against velocity) let indexPath = IndexPath(row: indexOfMajorCell, section: 0) collectionView.scrollToItem(at: indexPath, at: .left, animated: true) } } 如下:

predictions

然后我们可以在不使用连接的情况下进行绘图:

predictions <- bind_rows(
  d1 %>% gather_predictions(
    "m1" = lm(y ~ x, data = d1),
    "m2" = lm(y ~ x + z, data = d1),
    .pred = "y.pred"
  ),
  d2 %>% gather_predictions(
    "m1" = lm(y ~ x, data = d2),
    "m2" = lm(y ~ x + z, data = d2),
    .pred = "y.pred"
  )
)

这会呈现desired plot