dput a long list - shorten list but preserve structure

北城以北 提交于 2021-01-04 07:12:05

问题


If we want to make a reproducible question on a complex/large dataset for SO, we can use dput(head(df)) to reduce the size.

Is there a similar approach to reduce the size of complex nested lists with varying list lengths? I'm thinking an approach could be to take the first few elements from each list (say first 3) irrespective of individual list type (numeric, character etc.) and nested structure but I'm not sure how to do this.

#sample nested list
L <- list(
  list(1:10),
  list( list(1:10), list(1:10,1:10) ),
  list(list(list(list(1:10))))
)

Running dput(L) will naturally produce the structure for the whole list. Is there a simple way to reduce the overall length of this list (something like dput(head(L))?

I don't want to edit the structure of the list, e.g. I don't want to flatten first or anything - I just want to reduce the size of it and keep all attributes etc.

Thanks

Edit

@thelatemail solution works well:

rapply(L, f = head, n = 3, how = "list")

What if we had a data.frame in the list though, this approach splits the df into separate lists (which I assume is to be expected as list is specified in the rapply call)?. Is there a way to modify this so that it returns head(df) as a data.frame. df included:

L_with_df <- list(
  list(1:10),
  list( list(1:10), list(1:10,1:10), df = data.frame(a = 1:20, b = 21:40) ),
  list(list(list(list(1:10))))
)
rapply(L_with_df, f = head, n = 3, how = "list")

Edit 2

It seems rapply wont work on data.frames, see here.

However, rrapply here, which is an extension of rapply seems to do what I want:

library(rrapply)
rrapply(L_with_df, f = head, n = 3, dfaslist = FALSE)
# [[1]]
# [[1]][[1]]
# [1] 1 2 3


# [[2]]
# [[2]][[1]]
# [[2]][[1]][[1]]
# [1] 1 2 3


# [[2]][[2]]
# [[2]][[2]][[1]]
# [1] 1 2 3

# [[2]][[2]][[2]]
# [1] 1 2 3


# [[2]]$df
#   a  b
# 1 1 21
# 2 2 22
# 3 3 23


# [[3]]
# [[3]][[1]]
# [[3]][[1]][[1]]
# [[3]][[1]][[1]][[1]]
# [[3]][[1]][[1]][[1]][[1]]
# [1] 1 2 3


# Warning message:
# In rrapply(L_with_df, f = head, n = 3, dfaslist = FALSE) :
#   'dfaslist' is deprecated, use classes = 'data.frame' instead

#this produces different output?:
#rrapply(L_with_df, f = head, n = 3, classes = "data.frame")

回答1:


Let's create a nested list to serve as an example.

L <- list(
  list(1:10),
  list( list(1:10), list(1:10,1:10) ),
  list(list(list(list(1:10))))
)

Which has a structure of this:

str(L)
#List of 3
# $ :List of 1
#  ..$ : int [1:10] 1 2 3 4 5 6 7 8 9 10
# $ :List of 2
#  ..$ :List of 1
#  .. ..$ : int [1:10] 1 2 3 4 5 6 7 8 9 10
#  ..$ :List of 2
#  .. ..$ : int [1:10] 1 2 3 4 5 6 7 8 9 10
#  .. ..$ : int [1:10] 1 2 3 4 5 6 7 8 9 10
# $ :List of 1
#  ..$ :List of 1
#  .. ..$ :List of 1
#  .. .. ..$ :List of 1
#  .. .. .. ..$ : int [1:10] 1 2 3 4 5 6 7 8 9 10

I think using the recursive apply, rapply, with a f=unction of head can handle this without breaking the structure.

rapply(L, f=head, n=3, how="list")

Checks out:

str(rapply(L, f=head, n=3, how="list"))
#List of 3
# $ :List of 1
#  ..$ : int [1:3] 1 2 3
# $ :List of 2
#  ..$ :List of 1
#  .. ..$ : int [1:3] 1 2 3
#  ..$ :List of 2
#  .. ..$ : int [1:3] 1 2 3
#  .. ..$ : int [1:3] 1 2 3
# $ :List of 1
#  ..$ :List of 1
#  .. ..$ :List of 1
#  .. .. ..$ :List of 1
#  .. .. .. ..$ : int [1:3] 1 2 3


来源:https://stackoverflow.com/questions/64794738/dput-a-long-list-shorten-list-but-preserve-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!