[R] For loop with multiple iteration indexes

David L Carlson dc@r|@on @end|ng |rom t@mu@edu
Tue Sep 11 16:50:07 CEST 2018


Just for fun, there are ways to do this in R without an explicit loop:

> set.seed(42)
> dat <- matrix(rnorm(10*5), 10, 5)
> x <- sample(1:5)
> y <- sample(1:5)
> diag(cor(dat[, x], dat[, y]))
[1] -0.69156568 -0.06002371 -0.37492894  0.46477742 -0.37972866

You can use as.list() to convert the vector to a list.

> i <- seq_len(length(x))
> sapply(i, function(j) cor(dat[, x[j]], dat[, y[j]]))
[1] -0.69156568 -0.06002371 -0.37492894  0.46477742 -0.37972866
> xy <- cbind(x, y)
> sapply(i, function(j) cor(dat[, xy[j, ]])[1, 2])
[1] -0.69156568 -0.06002371 -0.37492894  0.46477742 -0.37972866

Change sapply() to lapply() to get list output.

----------------------------------------
David L Carlson
Department of Anthropology
Texas A&M University
College Station, TX 77843-4352

-----Original Message-----
From: R-help <r-help-bounces using r-project.org> On Behalf Of David Disabato
Sent: Monday, September 10, 2018 8:33 PM
To: r-help using r-project.org
Subject: Re: [R] For loop with multiple iteration indexes

Thank you everyone. After thinking about each response, I realized a fairly simple solution is available (obviously, other suggested approaches work as
well):

stopifnot(length(x) == length(y); stopifnot(length(x) > 0) r <- list() for (i in 1:length(x) ) {
   r[[i]] <- cor(x = dat[, x[i] ], y = dat[, y[i] ]) }
print(r)

On Mon, Sep 10, 2018 at 11:30 AM Berry, Charles <ccberry using ucsd.edu> wrote:

> I have a sense of deja vu:
>
> https://www.mail-archive.com/r-help@r-project.org/msg250494.html
>
> There is some good advice there.
>
> > On Sep 9, 2018, at 3:49 PM, David Disabato <ddisab01 using gmail.com> wrote:
> >
> > Hi R-help,
> >
> > I am trying to create a for loop with multiple iteration indexes. I 
> > don't want to use two different for loops nested together because I 
> > don't need the full matrix of the two indexes, just the diagonal 
> > elements (e.g.,
> i[1]
> > & j[1] and i[2] & j[2], but not i[1] & j[2]). Is there a way to 
> > specify both i and j in a single for loop? Here is a simplified 
> > example of pseudo-code where x and y are equally sized character 
> > vectors with column names and dat is their dataframe (obviously this 
> > code doesn't run in R,
> but
> > hopefully you perceive my goal):
> >
> > r <- list()
> > n <- 0
> > for (i in x; j in y) {
> >   n <- n + 1
> >   r[[n]] <- cor(x = dat[, i], y = dat[, j]) }
> > print(r)
> >
> > I realize there are other solutions to this particular correlation
> example,
> > but my actual problem is much more complicated, so I am hoping for a 
> > solution that generalizes across any code within the for loop.
>
> A more aRtful way (than a for loop) to approach this is with mapply:
>
>
> i <- head(colnames(mtcars))
> j <- tail(colnames(mtcars))
>
> r <- mapply(function(i, j, dat) cor( x = dat[, i], y = dat[, j]),
>        i=i , j=j , MoreArgs = list( dat = mtcars),
>        SIMPLIFY = FALSE, USE.NAMES = FALSE)
>
>
> and if you want, maybe USE.NAMES = paste(i, j, sep="_")
>
> Chuck
>
>

--
David J. Disabato, M.A.
Clinical Psychology Doctoral Student
George Mason University
ddisabat using gmu.edu

Email is not a secure form of communication as information and confidentiality cannot be guaranteed. Information provided in an email is not intended to be a professional service. In the case of a crisis or emergency situation, call 911.

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