I have a list of lists. A toy example similar is presented below. I want to extract the rownames from each list,and then store these rownames in either a new data frame or a new list of lists (in the same structure of the original).
Ideally the colnames or new list names would be identical to the list names from the list of lists.
note. the lists are all different lengths and must be taken into account. I would rather not fill the blank spaces with N/A.
dput(head(Chars_alive)):
list(FEB_games = list(GAME1 = structure(list(GAME1_Class = structure(c(2L, 1L, 5L, 4L, 3L), .Label = c("fighter", "paladin", "rouge", "sorcerer", "wizard"), class = "factor"), GAME1_Race = structure(c(3L, 1L, 4L, 3L, 2L), .Label = c("elf", "gnome", "human", "orc"), class = "factor"), GAME1_Alignment = structure(c(4L, 2L, 1L, 5L, 3L), .Label = c("CE", "CG", "LG", "NE", "NN"), class = "factor"), GAME1_Level = c(6, 7, 6, 7, 7), GAME1_Alive = structure(c(1L, 1L, 1L, 1L, 1L ), .Label = "y", class = "factor")), row.names = c("Stan", "Kenny", "Cartman", "Kyle", "Butters"), class = "data.frame"), GAME2 = structure(list(GAME2_Class = structure(c(5L, 2L, 4L, 1L), .Label = c("bard", "cleric", "fighter", "monk", "wizard"), class = "factor"), GAME2_Race = structure(c(3L, 2L, 4L, 1L), .Label = c("dwarf", "elf", "half-elf", "human" ), class = "factor"), GAME2_Alignment = structure(c(2L, 1L, 5L, 3L), .Label = c("CE", "CG", "LG", "NE", "NN"), class = "factor"), GAME2_Level = c(5, 5, 5, 5), GAME2_Alive = structure(c(2L, 2L, 2L, 2L), .Label = c("n", "y"), class = "factor")), row.names = c("Kenny", "Cartman", "Kyle", "Butters"), class = "data.frame")), MAR_games = list( GAME3 = structure(list(GAME3_Class = structure(c(2L, 1L, 5L, 3L), .Label = c("barbarian", "cleric", "monk", "ranger", "warlock"), class = "factor"), GAME3_Race = structure(c(2L, 3L, 2L, 1L), .Label = c("dwarf", "elf", "half-elf", "human" ), class = "factor"), GAME3_Alignment = structure(c(2L, 2L, 1L, 2L), .Label = c("CE", "LG", "LN"), class = "factor"), GAME3_Level = c(1, 1, 1, 1), GAME3_Alive = structure(c(2L, 2L, 2L, 2L), .Label = c("n", "y"), class = "factor")), row.names = c("Stan", "Kenny", "Cartman", "Butters"), class = "data.frame"), GAME4 = structure(list( GAME4_Class = structure(c(1L, 5L, 4L, 3L), .Label = c("fighter", "paladin", "rouge", "sorcerer", "wizard"), class = "factor"), GAME4_Race = structure(c(3L, 2L, 4L, 1L), .Label = c("dwarf", "elf", "half-elf", "human"), class = "factor"), GAME4_Alignment = structure(c(2L, 1L, 4L, 3L), .Label = c("CE", "CG", "LG", "LN"), class = "factor"), GAME4_Level = c(5, 5, 5, 5), GAME4_Alive = structure(c(2L, 2L, 2L, 2L), .Label = c("n", "y"), class = "factor")), row.names = c("Kenny", "Cartman", "Kyle", "Butters"), class = "data.frame")))
as.data.frame(rownames(Chars_alive[[1]][[1]])) -> GAME1 as.data.frame(rownames(Chars_alive[[2]][[1]])) -> GAME2
Because GAME1 and GAME2 have different lengths a data frame may not be ideal (my actual data has vastly different lengths between lists of lists).
for (i in Chars_alive) { for (j in i) rownames(j) -> x }
A for-loop could work but I am new to loops and do not know how to place all the jth elements into one new data frame or list.
ls2 <- list(Game1 <- rownames(Chars_alive[[1]][[1]]), Game2 <- rownames(Chars_alive[[1]][[2]]), Game3 <- rownames(Chars_alive[[2]][[1]]), Game4 <- rownames(Chars_alive[[2]][[2]]))
Perhaps making an new list outright would work, but I'd like to keep the structure of the original list if that was the case i.e. FEB_games > GAME1, GAME2 and MAR_games > GAME3, GAME4. Also I'd prefer to keep the list names the same i.e GAME1, GAME2, GAME3 and GAME4.
Ideal output would be either a data frame:
GAME1 GAME2 GAME3 GAME4 1 Stan Kenny Stan Kenny 2 Kenny Cartman Kenny Cartman 3 Cartman Kyle Cartman Kyle 4 Kyle Butters Butters Butters 5 Butters
Or a list:
Listname FEB_games GAME1 'Stan', 'Kenny', 'Cartman', 'Kyle', 'Butters' GAME2 'Kenny', 'Cartman', 'Kyle', 'Butters' MAR_games GAME3 'Stan', 'Kenny', 'Cartman', 'Butters' GAME4 'Kenny', 'Cartman', 'Kyle', 'Butters'
score:3
Hello I would use lapply in lapply like this. I call your list "list_games".
lapply(list_games, function(x){lapply(x, row.names)})
This gives you
$FEB_games
$FEB_games$GAME1
[1] "Stan" "Kenny" "Cartman" "Kyle" "Butters"
$FEB_games$GAME2
[1] "Kenny" "Cartman" "Kyle" "Butters"
$MAR_games
$MAR_games$GAME3
[1] "Stan" "Kenny" "Cartman" "Butters"
$MAR_games$GAME4
[1] "Kenny" "Cartman" "Kyle" "Butters"
If the rownames where of same length, you could save it as a data.frame with
do.call("rbind.data.frame", lapply(list_games, function(x){lapply(x, row.names)}))
This doesn't work here since there length of the rownames is not the same length. In this case you can do something like this:
res <- sapply(list_games, function(x){lapply(x, row.names)})
n.obs <- sapply(res , length)
seq.max <- seq_len(max(n.obs))
df <- data.frame(t(sapply(res, "[", i = seq.max)))
df
X1 X2 X3 X4 X5
1 Stan Kenny Cartman Kyle Butters
2 Kenny Cartman Kyle Butters <NA>
3 Stan Kenny Cartman Butters <NA>
4 Kenny Cartman Kyle Butters <NA>
If you need further explanation let me know. The last part was done like here
Credit To: stackoverflow.com