admin管理员组

文章数量:1398648

I'm trying to use ggplot in a loop to plot various dataset with different colours on top of eachother to inspect the data. My intention is to illustrate cross sectional data as in this gif Simpson Paradox. Ideally i would like to add a regression line aswell.

So far I manage to plot one dataset of one country at a time, which is then overwritten by calling the ggplot function again for the next country (i noticed dev.off() is just hiding the plot) Is it possible to additively call ggplot or must I assemble the data before?

for (i in 1:6) {
      print(i)
      plot(ggplot(subset(dataf, Country==vec[i] ), aes(x = varA, y = varB)) +  geom_point())
      dev.off()
 }

I'm trying to use ggplot in a loop to plot various dataset with different colours on top of eachother to inspect the data. My intention is to illustrate cross sectional data as in this gif Simpson Paradox. Ideally i would like to add a regression line aswell.

So far I manage to plot one dataset of one country at a time, which is then overwritten by calling the ggplot function again for the next country (i noticed dev.off() is just hiding the plot) Is it possible to additively call ggplot or must I assemble the data before?

for (i in 1:6) {
      print(i)
      plot(ggplot(subset(dataf, Country==vec[i] ), aes(x = varA, y = varB)) +  geom_point())
      dev.off()
 }
Share Improve this question asked Mar 26 at 17:26 user4672571user4672571 234 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 4

As you want an animation as in the referenced post you might be better off having a look at gganimate instead of creating separate plots.

Using some fake random example data:

library(ggplot2)
library(gganimate)
library(dplyr, warn = FALSE)
library(MASS)
#> 
#> Attaching package: 'MASS'
#> The following object is masked from 'package:dplyr':
#> 
#>     select

set.seed(5)

# Example data. 
# https://www.r-bloggers/2020/11/simpsons-paradox-and-misleading-statistical-inference/
mu <- lapply(c(0, 3, 6), rep, 2)
sigma <- lapply(1:3, \(x) rbind(c(x, -0.7), c(-0.7, x)))

df <- Map(
  \(mu, sigma) as.data.frame(mvrnorm(n = 100, mu = mu, Sigma = sigma)),
  mu, sigma
) |> 
  bind_rows(.id = "group")

df2 <- bind_rows(
  df |> mutate(group = "all", state = "1"),
  df |> mutate(state = "2")
)

ggplot(df2, aes(V1, V2)) +
  geom_point(,
    data = ~ filter(.x, group == "all")
  ) +
  geom_smooth(
    data = ~ filter(.x, group == "all"),
    color = "red", method = "lm", se = FALSE
  ) +
  geom_point(aes(color = group),
    data = ~ filter(.x, group != "all")
  ) +
  geom_smooth(aes(group = group),
    data = ~ filter(.x, group != "all"),
    color = "red", method = "lm", se = FALSE
  ) +
  transition_states(state) +
  enter_fade() +
  exit_fade()
#> `geom_smooth()` using formula = 'y ~ x'
#> `geom_smooth()` using formula = 'y ~ x'

Note that questions are supposed to provide complete reproducible inputs but we will use CO2 which comes with R.

You don't need a loop for this. This plots uptake vs conc with a different color for each Type.

library(ggplot2)
ggplot(CO2, aes(conc, uptake, col = Type)) + geom_point()

I personally prefer the `gganimate` version of @stefan. Here is a way how we could do it with a for loop:

library(ggplot2)

dataf <- data.frame(
  varA = rep(1:10, 6),
  varB = c(rnorm(10, 1), rnorm(10, 2), rnorm(10, 3),
           rnorm(10, 4), rnorm(10, 5), rnorm(10, 6)),
  Country = rep(paste0("Country_", LETTERS[1:6]), each = 10)
)

vec <- unique(dataf$Country)

p <- ggplot() + theme_minimal()


for (i in seq_along(vec)) {
  subset_data <- subset(dataf, Country == vec[i])
  p <- p +
    geom_point(data = subset_data, aes(x = varA, y = varB), color = "grey") +
    geom_smooth(data = subset_data, aes(x = varA, y = varB), method = "lm",
                se = FALSE, color = "grey")
}

p <- p + 
  geom_smooth(data = dataf, aes(x = varA, y = varB), 
              method = "lm", se = FALSE, color = "black", linetype = "dashed")

p

本文标签: rPlotting different datasets on top of eachother for illustrating a possible Simpson paradoxStack Overflow