1
votes

My looping structure below works great. However, if we had: m = data.frame(po = c(1,2,1,2), ou = rep(1,4)) and input = rev(expand.grid(ou = seq_len(max(m$ou)), po = seq_len(max(m$po)))) and I expected the same output as now (i.e., a list of two elements),

then, how should the lapply(input, ... change?

m = list(A = data.frame(po = c(1,2,1,2), ou = rep(1,4)))
# if: `m = data.frame(po = c(1,2,1,2), ou = rep(1,4))`

input <- lapply(m, function(i) rev(expand.grid(ou = seq_len(max(i$ou)),
 po = seq_len(max(i$po)))))

# if: `input = rev(expand.grid(ou = seq_len(max(m$ou)), po = seq_len(max(m$po))))`

lapply(input, function(inp) Map(function(p, o)  ## Then, how should this change?
  do.call(rbind, lapply(m, function(m1)
    m1[m1$po == p & m1$ou == o, , drop = FALSE])), inp$po, inp$ou))

#==== Current & Desired Output:
#$A
#$A[[1]]
    po ou
A.1  1  1
A.3  1  1

#$A[[2]]
    po ou
A.2  2  1
A.4  2  1
1
I'm a little confused what you are asking. What is the change to the input that would require you to change the lapply statement?qdread
Aha OK in that case just wrap it as lapply(list(input), ...)qdread

1 Answers

0
votes

As far as I can see the minimal amount of change to your code required to return the same input in the alternative case is to wrap both input and m in the function list() so that they are both lists of length 1 with that single element being a data frame. Data frames are themselves lists (each column of the data frame is an element of the list). Because of this, if you do not wrap the data frames in list(), the lapply statement will try to iterate over the columns of the data frame and fail.

m <- data.frame(po = c(1,2,1,2), ou = rep(1,4))

input <- rev(expand.grid(ou = seq_len(max(m2$ou)), po = seq_len(max(m2$po))))

lapply(list(input), function(inp) Map(function(p, o)  ## How should this change?
  do.call(rbind, lapply(list(m), function(m1)
    m1[m1$po == p & m1$ou == o, , drop = FALSE])), inp$po, inp$ou))