问题
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