[R] question about for loop

Avi Gross @v|gro@@ @end|ng |rom ver|zon@net
Sat Dec 25 01:54:04 CET 2021


Suggestion to consider another approach:

Once various errors are fixed, the program being done basically sounds like
you want to repeat a sequence of actions one per ROW of a data.frame. As it
happens, the action to perform is based on a second data.frame given to
ggplot, with parts dynamically inserted from the variables in one row.

So consider making a function with a name like graph_it() that does what you
want when passed three named arguments. I mean it takes arguments with names
like alpha, beta and gamma and then use the pmap() function (part of the
tidyverse unfortunately in the purr package) along with the function you
want:

Typing:

pmap(.l=mac2, .f=graph_it)

Will implicitly perform your functionality one row after another without an
explicit loop and often faster than nested loops would be. I have used the
technique to replace a deeply nested loop that generates all combinations of
multiple categorical variables (about a million) into a data.frame, then do
something with each one fairly efficiently.

If nothing else, it would make this problem a tad simpler by not needing
subscripts.

-----Original Message-----
From: R-help <r-help-bounces using r-project.org> On Behalf Of Andrew Simmons
Sent: Friday, December 24, 2021 5:37 PM
To: Kai Yang <yangkai9999 using yahoo.com>
Cc: R-help Mailing List <r-help using r-project.org>
Subject: Re: [R] question about for loop

y, c, and f only exist in the context of mac2 If you want to use them,
you'll have to write mac2$y, mac2$c, or mac2$f (or the [[ versions
mac2[["y"]], mac2[["c"]], or mac2[["f"]]) Combining that with index i would
then look like mac2$y[[i]] or mac2[[i, "y"]]

Also, I think you want to use aes_string instead of aes (since you want
those expressions within aes to be evaluated) Something like this seems to
work for me:


`%>%` <- magrittr::`%>%`


writeLines(FILE <- tempfile(), text =
r"{y,c,f
hwy,cyl,hwy_cyl2
cty,class,cty_class2}")


mac2 <- readr::read_csv(FILE)
for (i in seq_len(nrow(mac2))) {
    ggplt <- ggplot2::mpg %>%
        dplyr::filter(hwy < 35) %>%
        ggplot2::ggplot(
            ggplot2::aes_string(
                x = "displ",
                y = mac2[[i, "y"]],
                color = mac2[[i, "c"]]
            )
        ) +
        ggplot2::geom_point() +
        ggplot2::ylab(mac2[[i, "y"]]) +
        ggplot2::guides(
            color = ggplot2::guide_legend(title = mac2[[i, "c"]])
        )
    ggplot2::ggsave(
        filename = tempfile(
            mac2[[i, "f"]],
            fileext = ".jpg"
        ),
        plot = ggplt,
        width = 9, height = 6, dpi = 1200
    )
}


unlink(FILE)


runs fine on my computer, but might look more like this for you:


library(magrittr)
library(ggplot2)
library(dplyr)
library(readr)


mac2 <- read_csv("C:/temp/mac2.csv")
for (i in seq_len(nrow(mac2))) {
    ggplt <- mpg %>%
        filter(hwy < 35) %>%
        ggplot(
            aes_string(
                x = "displ",
                y = mac2[[i, "y"]],
                color = mac2[[i, "c"]]
            )
        ) +
        geom_point() +
        ylab(mac2[[i, "y"]]) +
        guides(
            color = guide_legend(title = mac2[[i, "c"]])
        )
    ggsave(
        filename = paste0("C:/temp/", mac2[[i, "f"]], ".jpg"),
        plot = ggplt,
        width = 9, height = 6, dpi = 1200
    )
}


try reading through aes and aes_string, and keep in mind that columns in
data frames aren't R variables (where they are in Excel). If you want to use
columns like they are variables, you can try using `with`. For example:


library(magrittr)
library(ggplot2)
library(dplyr)
library(readr)


mac2 <- read_csv("C:/temp/mac2.csv")
for (i in seq_len(nrow(mac2))) {
    with(mac2[i, ], {
        ggplt <- mpg %>%
            filter(hwy < 35) %>%
            ggplot(
                aes_string(
                    x = "displ",
                    y = y,
                    color = c
                )
            ) +
            geom_point() +
            ylab(y) +
            guides(
                color = guide_legend(title = c)
            )
        ggsave(
            filename = paste0("C:/temp/", f, ".jpg"),
            plot = ggplt,
            width = 9, height = 6, dpi = 1200
        )
    })
}




On Fri, Dec 24, 2021 at 4:48 PM Kai Yang via R-help <r-help using r-project.org>
wrote:

> Hello Team,
> I create a csv file (mac2) to save parameter values. the file looks like:
>
> y,c,f
> hwy,cyl,hwy_cyl2
> cty,class,cty_class2
>
> Then I load the file into R and apply the parameters y, c, f in for 
> loop, see my code below:
> library(ggplot2)
> library(tidyverse)
> library(readr)
> mac2 <- read_csv("C:/temp/mac2.csv")
> View(mac2)
> for (i in seq(nrow(mac2))){
>   mpg %>%
>     filter(hwy <35) %>%
>     ggplot(aes(x = displ, y = get(y[i]), color = get(c[i]) )) +
>     geom_point()+
>     ylab(y[i]) +
>     guides(color = guide_legend(title = c[i])) 
> ggsave(paste0("c:/temp/",f[i],".jpg"),width = 9, height = 6, dpi = 
> 1200, units = "in") }
>
> but I got an error message: "Error in dots_list(..., title = title, 
> subtitle = subtitle, caption = caption,  :  object 'y' not found"
> Does anyone know how to fix the problem?
> Thanks,
> Kai
>
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see 
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

	[[alternative HTML version deleted]]

______________________________________________
R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list