Как извлечь имена строк всех списков в список списков и сохранить их в новом фрейме данных или в списке списков - PullRequest
1 голос
/ 01 апреля 2019

У меня есть список списков.Пример игрушечного аналога представлен ниже.Я хочу извлечь имена строк из каждого списка, а затем сохранить эти имена строк либо в новом фрейме данных, либо в новом списке списков (в той же структуре оригинала).

В идеале имена столбцов или новые списки должны совпадать с именами списков из списка списков.

note.списки имеют разную длину и должны быть приняты во внимание.Я бы предпочел не заполнять пробелы с помощью 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

Поскольку GAME1 и GAME2 имеютразные длины фрейм данных может быть не идеальным (мои фактические данные имеют разную длину между списками списков).

for (i in Chars_alive) {
  for (j in i)
    rownames(j) -> x
}

Цикл for может работать, но я новичок в циклах и не знаю, как поместить все j-ые элементы в один новый фрейм данных или список.

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]]))

Возможно, создание нового списка было бы правильным, но я бы хотел сохранить структуру исходного списка, если бы это было так, т.е. FEB_games> GAME1, GAME2 и MAR_games> GAME3, GAME4.Также я бы предпочел, чтобы имена в списке оставались неизменными, например, GAME1, GAME2, GAME3 и GAME4.


Идеальным выводом будет либо фрейм данных:

    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   

, либо список:

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'

1 Ответ

2 голосов
/ 01 апреля 2019

Здравствуйте, я бы использовал lapply в lapply вот так. Я называю ваш список "list_games".

lapply(list_games, function(x){lapply(x, row.names)})

Это дает вам

$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"

Если имена строк имеют одинаковую длину, вы можете сохранить их как data.frame с

do.call("rbind.data.frame", lapply(list_games, function(x){lapply(x, row.names)}))

Здесь это не работает, поскольку длина имен строк не одинакова. В этом случае вы можете сделать что-то вроде этого:

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>

Если вам нужны дальнейшие объяснения, дайте мне знать. Последняя часть была сделана как здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...