У меня есть вложенный список с 3 уровнями:
m = list(try1 = list(list(court = c("jack", "queen", "king"),
suit = list(diamonds = 2, clubs = 5)),
list(court = c("jack", "queen", "king"),
suit = list(diamonds = 45, clubs = 67))),
try2 = list(list(court = c("jack", "queen", "king"),
suit = list(diamonds = 400, clubs = 300)),
list(court = c("jack", "queen", "king"),
suit = list(diamonds = 5000, clubs = 6000))))
> str(m)
List of 2
$ try1:List of 2
..$ :List of 2
.. ..$ court: chr [1:3] "jack" "queen" "king"
.. ..$ suit :List of 2
.. .. ..$ diamonds: num 2
.. .. ..$ clubs : num 5
..$ :List of 2
.. ..$ court: chr [1:3] "jack" "queen" "king"
.. ..$ suit :List of 2
.. .. ..$ diamonds: num 45
.. .. ..$ clubs : num 67
$ try2:List of 2
..$ :List of 2
.. ..$ court: chr [1:3] "jack" "queen" "king"
.. ..$ suit :List of 2
.. .. ..$ diamonds: num 400
.. .. ..$ clubs : num 300
..$ :List of 2
.. ..$ court: chr [1:3] "jack" "queen" "king"
.. ..$ suit :List of 2
.. .. ..$ diamonds: num 5000
.. .. ..$ clubs : num 6000
Для каждого подсписка в try1
и try2
мне нужно извлечь подсписок suit
и связать его элементы так, чтобы получилсяфрейм данных представлен в длинном формате с 4 столбцами - value
(значение масти), suit
(который определяет, из какого набора исходит значение, например, алмазы или булавы), iter
(чтобы определить, какой подсписокиск принадлежит, то есть 1 или 2) и try
(try1 или try2).
Я мог бы добиться этого, используя комбинацию expand.grid()
и mapply()
:
grd = expand.grid(try = names(m), iter = 1:2, suit = c("diamonds", "clubs"))
grd$value = mapply(function(x, y, z) m[[x]][[y]]$suit[[z]], grd[[1]], grd[[2]], grd[[3]])
Результат:
> grd
try iter suit value
1 try1 1 diamonds 2
2 try2 1 diamonds 400
3 try1 2 diamonds 45
4 try2 2 diamonds 5000
5 try1 1 clubs 5
6 try2 1 clubs 300
7 try1 2 clubs 67
8 try2 2 clubs 6000
Однако мне было интересно, есть ли более общий / краткий способ воспроизведения вышеуказанного результата (предпочтительно в базе R)? Я думал об извлеченииВыделить элемент из каждого подсписка и затем рекурсивно использовать что-то вроде stack()
в результирующем списке:
rapply(m, function(x) setNames(stack(x), names(x)))
Но это выдает ошибку, я не совсем уверен, почему, и я не знаю, что использоватьна своем месте.