nouse
nouse

Reputation: 3461

looping through two variables in lists

I have a list of lists with distance matrices:

obs <- list(AA=list(A=dist(runif(100)),
                 B=dist(runif(100)),
                 C=dist(runif(100))),
            BB=list(A=dist(runif(100)),
                    B=dist(runif(100)),
                    C=dist(runif(100))))

obs <- lapply(obs, function(x)
  lapply(x, function(x) as.data.frame(as.matrix(x))))

And another one with however only one hierarchy:

distances <- lapply(list(A=rnorm(100),B=rnorm(100),C=rnorm(100)), function(x)
  as.data.frame(as.matrix(dist(x, "euclidean"))))

I would like to compare all the matrices in the 2nd level of obs and in the first level of distances, if their names match (obs[i]$A with distances$A, B with B, C with C; never all combinations!). After trying to run sapply within lapply, which failed, i came to for loops, during which i store results and extract some values from them:

coef <- pvals <- res <- vector("list", length(names(obs)))
library(vegan)
for(i in (names(obs)){ 
  res[[i]]$A  <- mantel(obs[[i]]$A, distances$A, "spearman", perm=999)
  #tmp <-  res[[i]]$A
  #coef[i]$A <- tmp[i]$statistic
  #pvals[i]$A <- tmp[i]$signic
}

I loop through the first level of obs and fix the second level, and proceed this for obs[[i]]$A and B (not pasting the # lines from above again to save space):

    for(i in (names(obs)){ 
      res[[i]]$B  <- mantel(obs[[i]]$B, distances$B, "spearman", perm=999)
      ...
    }
    for(i in (names(obs)){ 
      res[[i]]$C  <- mantel(obs[[i]]$C, distances$C, "spearman", perm=999)
      ...
    }

The question is now to loop through the second level (obs[i]$A,B,C) as well, while also pointing to the correct matrix in distances. Would it be better to put the three loops above into one parental loop (through obs[i][j]) or is there a way to use lapply? Thank you!

Upvotes: 0

Views: 38

Answers (1)

hplieninger
hplieninger

Reputation: 3494

If I understood your question correctly, I would do something like this:

for(i in seq_along(obs)) {         # 1st level of obs

    for (j in names(obs[[i]])) {   # 2nd level of obs, 1st level of distances

        res[[i]][[j]] <- mantel(obs[[i]][[j]], distances[[j]], "spearman", perm=999)

    }
}

Upvotes: 1

Related Questions