Tom
Tom

Reputation: 2341

Looping through a sub list, where the "sub sub" list stays constant

I would like to loop through a sub list, where the "sub sub" list stays constant. All code mentioned by me is just the reproducible example (please note that the actual data is really large) and should work without issue.

I have a list of lists which each have 2 sub lists as follows:

library(data.table)  
library(mice)
df <- fread(
    "A   B  C  D  E  F  iso   year   
     0   A   NA  1  NA  NA  NLD   2009   
     1   Y   NA  2  NA  NA  NLD   2009   
     0   Q   NA  3  NA  NA  AUS   2011   
     1   NA  NA  4  NA  NA  AUS   2011   
     0   0   NA  7  NA  NA  NLD   2008   
     1   1   NA  1  NA  NA  NLD   2008   
     0   1   NA  3  NA  NA  AUS   2012   
     0   NA  1   NA  1  NA  ECU   2009   
     1   NA  0   NA  2  0   ECU   2009   
     0   NA  0   NA  3  0   BRA   2011   
     1   NA  0   NA  4  0   BRA   2011   
     0   NA  1   NA  7  NA  ECU   2008   
     1   NA  0   NA  1  0   ECU   2008   
     0   NA  0   NA  3  2   BRA   2012   
     1   NA  0   NA  4  NA  BRA   2012",
   header = TRUE
)

# Creates a list
df_iso <- split(df, df$iso) # Creates a list of dataframes

# Creates a list of lists
mylist.names <- names(df_iso)
df_iso_list <- vector("list", length(mylist.names))
names(df_iso_list) <- mylist.names

f <- function(x) return(list(a = list(), b = list()))
new_nested <- lapply(df_iso, f)

Now new_nested$AUS$a accesses the list a of sub list AUS. So far so good.

I would like to redistribute the two lists (df_iso_1, df_iso_2) below to the list structure I just created.

df_iso_1 = list()
for (i in 1:length(df_iso))  {
  tryCatch({
    df_iso_1 [[i]] <- mice(df_iso[[i]], m=1, maxit = 5, seed=1)
    if (i==1000) stop("stop")
  }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
}

df_iso_2 = list()
for (i in 1:length(df_iso))  {
  tryCatch({
    df_iso_2 [[i]] <- mice(df_iso[[i]], m=1, maxit = 5, seed=2)
    if (i==1000) stop("stop")
  }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
}
names(df_iso_1) <- names(df_iso)
names(df_iso_2) <- names(df_iso)

Although new_nested$AUS$a accesses the list, I would like to loop through the iso codes with an index instead of referring to them by name:

for (n in length(df_iso)) {
new_nested$[i]$a <- df_iso_1[n]
}

This does however not work. What is the correct syntax of looping through these lists?

Desired output:

From df_iso_1 and df_iso_2, the mids objects are pooled per iso code. In other words, all iso codes are put together in the new structure:

So new_nested has its list NLD filled with the NLD mids objects from df_iso_1 and df_iso_2, and its list list AUS filled with the AUS mids objects from df_iso_1 and df_iso_2.

Upvotes: 2

Views: 97

Answers (1)

Cole
Cole

Reputation: 11255

Here are two approaches. The first is to fix your loop with seq_len(length(df_iso)) and to match your output, changing your df_iso_1[n] to df_iso1[[n]]:

for (n in seq_len(length(df_iso))) {
  new_nested[[names(df_iso)[n]]]$a <- df_iso_1[[n]] 
  new_nested[[names(df_iso)[n]]]$b <- df_iso_2[[n]]
}

new_nested$AUS$a

Class: mids
Number of multiple imputations:  1 
Imputation methods:
   A    B    C    D    E    F  iso year 
  ""   ""   ""   ""   ""   ""   ""   "" 
PredictorMatrix:
  A B C D E F iso year
A 0 0 0 0 0 0   0    1
B 0 0 0 0 0 0   0    0
C 0 0 0 0 0 0   0    0
D 1 0 0 0 0 0   0    1
E 0 0 0 0 0 0   0    0
F 0 0 0 0 0 0   0    0
Number of logged events:  6 
  it im dep      meth out
1  0  0      constant   B
2  0  0      constant   C
3  0  0      constant   E
4  0  0      constant   F
5  0  0      constant iso
6  0  0     collinear   D

The second approach is to use mapply to loop through each element of your df_iso_n lists to combine them into a new matrix of lists:

mapply(list, df_iso_1, df_iso_2)

#     AUS     BRA     ECU     NLD    
#[1,] List,21 List,21 List,21 List,21
#[2,] List,21 List,21 List,21 List,21

mapply(list, df_iso_1, df_iso_2)[, 'AUS']

[[1]]
Class: mids
Number of multiple imputations:  1 
Imputation methods:
   A    B    C    D    E    F  iso year 
  ""   ""   ""   ""   ""   ""   ""   "" 
PredictorMatrix:
  A B C D E F iso year
A 0 0 0 0 0 0   0    1
B 0 0 0 0 0 0   0    0
C 0 0 0 0 0 0   0    0
D 1 0 0 0 0 0   0    1
E 0 0 0 0 0 0   0    0
F 0 0 0 0 0 0   0    0
Number of logged events:  6 
  it im dep      meth out
1  0  0      constant   B
2  0  0      constant   C
3  0  0      constant   E
4  0  0      constant   F
5  0  0      constant iso
6  0  0     collinear   D

[[2]]
Class: mids
Number of multiple imputations:  1 
Imputation methods:
   A    B    C    D    E    F  iso year 
  ""   ""   ""   ""   ""   ""   ""   "" 
PredictorMatrix:
  A B C D E F iso year
A 0 0 0 0 0 0   0    1
B 0 0 0 0 0 0   0    0
C 0 0 0 0 0 0   0    0
D 1 0 0 0 0 0   0    1
E 0 0 0 0 0 0   0    0
F 0 0 0 0 0 0   0    0
Number of logged events:  6 
  it im dep      meth out
1  0  0      constant   B
2  0  0      constant   C
3  0  0      constant   E
4  0  0      constant   F
5  0  0      constant iso
6  0  0     collinear   D

Also, it still would be a good idea to consider refactoring your code. This largely does everything in 3 lines:

seeds = c(1,2)

by(data = df, INDICES = df$iso,
   FUN = function(ISO) lapply(seeds, function(seed) mice(ISO, m = 1, maxit = 5, seed = seed)))

df$iso: AUS
[[1]]
Class: mids
Number of multiple imputations:  1 
Imputation methods:
   A    B    C    D    E    F  iso year 
  ""   ""   ""   ""   ""   ""   ""   "" 
PredictorMatrix:
  A B C D E F iso year
A 0 0 0 0 0 0   0    1
B 0 0 0 0 0 0   0    0
C 0 0 0 0 0 0   0    0
D 1 0 0 0 0 0   0    1
E 0 0 0 0 0 0   0    0
F 0 0 0 0 0 0   0    0
Number of logged events:  6 
  it im dep      meth out
1  0  0      constant   B
2  0  0      constant   C
3  0  0      constant   E
4  0  0      constant   F
5  0  0      constant iso
6  0  0     collinear   D

[[2]]
Class: mids
Number of multiple imputations:  1 
Imputation methods:
   A    B    C    D    E    F  iso year 
  ""   ""   ""   ""   ""   ""   ""   "" 
PredictorMatrix:
  A B C D E F iso year
A 0 0 0 0 0 0   0    1
B 0 0 0 0 0 0   0    0
C 0 0 0 0 0 0   0    0
D 1 0 0 0 0 0   0    1
E 0 0 0 0 0 0   0    0
F 0 0 0 0 0 0   0    0
Number of logged events:  6 
  it im dep      meth out
1  0  0      constant   B
2  0  0      constant   C
3  0  0      constant   E
4  0  0      constant   F
5  0  0      constant iso
6  0  0     collinear   D

---------------------------------------------------- 
df$iso: BRA
[[1]]
...

Upvotes: 1

Related Questions