简体   繁体   中英

for over list with different lengths in lapply

I have complicated function which includes many lists with different lengths. I would like to pass the same function over these lists using lapply but I got NULL . I know my problem but do not know how to fix it.

My first problem is here:

AFA <- lapply(1:m, function(i) A[[i]][AA[[i]]])

AFA is a list of two elements. Each element of list contains 10 elements.

FA <- lapply(1:m, function(i) { which(AFA[[i]][[j]] %in% c(2, 7))})

FA tried to see which elements of the 10 elements are 2 or 7.

I know that lapply here is not help. But I could not use mapply in this case.

My second problem is:

`lapply(nAA2, function(x) if (x > 0) { ##if the length of the function is not zero.

      for(j in 1:m){
        for (i in 1:x) ....` 

nAA2 is a list of two elements. The length of the first element is 1 while 2 for the second element. Hence, the code says this:

for the length of the first element. if (AFA[[j]][[FA[[i]]]] == 2) this means, check each element of AFA using FA and since FA is also a list then I used FA[[i]] .

Instead to say:

for ( i in 1:length(nAA2[[1]]) .... and for ( i in 1:length(nAA2[[2]]) ....

I would like to merge then in one code.

Here is my full code with my comments explaining the code lines:

A1 <- c(0, 2, 3, 4, 4,
        0, 0, 3, 4, 1,
        0, 0, 0, 4, 1,
        0, 0, 0, 0, 3,
        0, 0, 0, 0, 0)
A1  <- matrix(A1, 5, 5)
A2 <- c(0, 2, 3, 2, 4,
        0, 0, 3, 4, 1,
        0, 0, 0, 4, 1,
        0, 0, 0, 0, 3,
        0, 0, 0, 0, 0)
A2  <- matrix(A2, 5, 5)

A <- list(A1, A2)
m <- length(A)

AA <- lapply(A, function(x) x > 0)
AA2 <- lapply(A, function(x) x %in% c(2, 7))

AA[is.na(AA)] <- FALSE
AA2[is.na(AA2)] <- FALSE

nAA <- lapply(AA, function(x) sum(x, na.rm = TRUE))
nAA2 <- lapply(AA2, function(x) sum(x, na.rm = TRUE))

AFA <- lapply(1:m, function(i) A[[i]][AA[[i]]])
llA <- lapply(1:m, function(i) double(nAA[[i]]+nAA2[[i]]))
luA <- lapply(1:m, function(i) double(nAA[[i]]+nAA2[[i]]))
FA <-  lapply(1:m, function(i) { which(AFA[[i]][[j]] %in% c(2, 7))}) ## here 
AFA is a list of two elements. I would like to access the first element of 
the list,  and then check each element. I know this is wrong, but how to fix 
it with `mapply`. 


for(j in 1:m){

}
lapply(nAA2, function(x) if (x > 0) { ##here to check that they are not zero. That is we have number equal to 2 or 7.

  for(j in 1:m){ 
    for (i in 1:x) { #here I wouldl like to loop over the length of the 
    first list and then the second list.
      if (AFA[[j]][[FA[[i]]]] == 2) {
        # t
        llA[[j]][nAA[[i]] + i] <- 2
        luA[[j]][nAA[[i]] + i] <- 5 
      }

The expected output should be like this:

[[1]][[1]]
2
[[1]][[2]]
2


[[2]][[1]]
5
[[2]][[2]]
5

Partial answer (only first problem):

FA <- lapply(1:m, function(i) { which(AFA[[i]][[j]] %in% c(2, 7))})

FA tried to see which elements of the 10 elements are 2 or 7.

I think you are using lapply the wrong way. lapply loops over every object in a list, so to identify the vector elements which are either 2 or 7, just use

FA <-  lapply(AFA, function(x) which(x %in% c(2, 7)))

> FA
[[1]]
[1] 1

[[2]]
[1] 1 3

The output shows you the positions of vector elements that are either 2 or 7 in the both vectors of list AFA .

Solution for problem 2:

To be able to perform multiple tests and assign the corresponding values wo luA and llA , we first create new lists/vectors.

An example:

testvalues <- list(2, c(7, 10), c(3, 5))
llAvalues <- c(2, 1, 3)
luAvalues <- c(5, 2, 4)

These include the values to be tested for in testvalues , and the values to be given to llA and luA for the corresponding tests. The new objects must have the same lengths!

Now we use a nested mapply call to loop through AFA on the outer level, and through each test on the inner level.

llA <- mapply(function(v, w) mapply(function(x,y) ifelse(v[w] %in% x, y, 0), testvalues, llAvalues), AFA, FA)
luA <- mapply(function(v, w) mapply(function(x,y) ifelse(v[w] %in% x, y, 0), testvalues, luAvalues), AFA, FA)

Afterwards, we delete all generated 0 (could also use NA ).

llA <- lapply(llA, function(x) x[x != 0])

which leaves us with the desired output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM