1

I'm creating a graph with values located in different columns of a data frame. Specifically from columns x=5,7,9,11 and y=6,8,10,12.

Here is a small dataset:

structure(list(number = 1:4, Start = c(2, 2, 2, 2), End = c(42, 
42, 48, 48), Seq = c(0.1, 0.1, 0.1, 0.1), `50 sec` = c(0.1, 
0.1, 0.1, 0.1), `t test 50 sec` = c(0.001, 0.001, 0.001, 0.001
), `200 sec` = c(1.5, 1.5, 1.5, 1.5), `t test 200 sec` = c(0.7, 
0.7, 0.7, 0.7), `800 sec` = c(0.1, 1.1, 2.1, 3.1), 
    `t test 800 sec` = c(0.001, 0.001, 0.001, 0.001), `3200 sec` = c(0.2, 
    0.2, 0.2, 0.2), `t test 3200 sec` = c(0.01, 0.01, 0.01, 0.01
    ), `SR` = c(0, 0, 0, 0)), row.names = 3:6, class = "data.frame")

To do it I created a for loop to access those columns. however, the variable in my loops is not changing and the graph I'm getting only have the data from the first column.

Here is the code I'm using:

 timepoints=4
 plot=ggplot(data=newdata, aes(x=newdata[,5], y=-log10(newdata[,6])),na.rm=TRUE) + geom_point()
 for (f in 2:timepoints){
 plot + geom_point(aes(x=newdata[,(f*2)+3], y=-log10(newdata[,(f*2)+4])),na.rm=TRUE)
 }

I tried introducing a local variable, but didn't work either.

timepoints=4
local({
f=f
plot=ggplot(data=newdata, aes(x=newdata[,5], y=-log10(newdata[,6])),na.rm=TRUE) + geom_point()
for (f in 2:timepoints){
plot + geom_point(aes(x=newdata[,(f*2)+3], y=-log10(newdata[,(f*2)+4])),na.rm=TRUE)
}})
stefan
  • 90,330
  • 6
  • 25
  • 51
  • 1
    You're not assigning the result of your `plot` inside your `for` loop to anything. That's why the result doesn't change. You may also need to be aware of R's habit of evaluating lazily in `for` loops... – Limey Feb 21 '23 at 19:00

1 Answers1

1

The ggplot2 way of adding multiple layers to a plot would be to use a list, i.e. use lapply instead of a for loop:

timepoints <- 4

library(ggplot2)

ggplot(data = newdata) +
  lapply(seq(timepoints), function(f) {
    geom_point(aes(x = newdata[, (f * 2) + 3], y = -log10(newdata[, (f * 2) + 4])))
  })

However, the recommended way would be to reshape your data to tidy format using e.g. tidyr::pivot_longer which allows to create your plot using just one geom_point:


library(dplyr, warn = FALSE)
library(tidyr)

newdata_tidy <- newdata %>%
  rename_with(~ paste0("value ", .x), matches("^\\d")) %>%
  pivot_longer(-c(1:4, ncol(.)), names_to = c(".value", "name"), names_pattern = "(.*) (\\d+ sec)$")

ggplot(data = newdata_tidy, aes(x = value, y = -log10(`t test`), color = name)) +
  geom_point()

stefan
  • 90,330
  • 6
  • 25
  • 51