简体   繁体   中英

tidyr equivalent of reshape2::melt() for deeply nested lists of vectors

Using reshape2 , it's easy to convert a deeply nested list of vectors to a long data.frame which includes information on each value's original list position.

# generate nested list of depth 3 with 2 branches at each level
n_l <- purrr::array_tree(
  array(1:2^3, rep_len(2, 3))
)

m_n_l <- reshape2::melt(n_l)

# this provides a df of values where original list position is labelled using 
# [n_dimensions] columns each with [n_branches] values. yay! that's what I want
m_n_l

#    value L3 L2 L1
# 1      1  1  1  1
# 2      5  2  1  1
# 3      3  1  2  1
# 4      7  2  2  1
# 5      2  1  1  2
#        ...

# [reshape2::melt() also handles the case where leaf node vectors have 
# arbitrary number of elements]
reshape2::melt(rapply(n_l, function(x) x * 1:sample(1:3, 1)))

reshape2 is now retired, and its users are being encouraged to use tidyr . However, I can't find a tidyr way to replicate the above functionality of reshape2::melt() . pivot_longer() , hoist() , and unnest() seem like the functions replacing melt() , but they seem to be specialised to the particular cases of data.frames or lists of data.frames.

Can tidyr do this?

One option using rrapply could be:

Reduce(rbind, rrapply(n_l, f = function(x, .xpos) c(.xpos, x), how = "flatten"))

     [,1] [,2] [,3] [,4]
init    1    1    1    1
        1    1    2    5
        1    2    1    3
        1    2    2    7
        2    1    1    2
        2    1    2    6
        2    2    1    4
        2    2    2    8

But if you are looking for a specific tidyverse option, then one not very compact one could be:

enframe(n_l) %>%
 mutate(value = map(value, ~ enframe(., name = "name2"))) %>%
 unnest(value) %>%
 mutate(value = map(value, ~ enframe(., name = "name3"))) %>%
 unnest(value) %>%
 mutate(value = unlist(value))

   name name2 name3 value
  <int> <int> <int> <int>
1     1     1     1     1
2     1     1     2     5
3     1     2     1     3
4     1     2     2     7
5     2     1     1     2
6     2     1     2     6
7     2     2     1     4
8     2     2     2     8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM