-
Notifications
You must be signed in to change notification settings - Fork 418
Expand file tree
/
Copy pathhoist.Rd
More file actions
202 lines (173 loc) · 6.3 KB
/
Copy pathhoist.Rd
File metadata and controls
202 lines (173 loc) · 6.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/rectangle.R
\name{hoist}
\alias{hoist}
\alias{unnest_longer}
\alias{unnest_wider}
\alias{unnest_auto}
\title{Rectangle a nested list into a tidy tibble}
\usage{
hoist(
.data,
.col,
...,
.remove = TRUE,
.simplify = TRUE,
.ptype = list(),
.transform = list()
)
unnest_longer(
data,
col,
...,
values_to = NULL,
indices_to = NULL,
indices_include = NULL,
names_repair = "check_unique",
simplify = TRUE,
ptype = list(),
transform = list()
)
unnest_wider(
data,
col,
...,
names_sep = NULL,
simplify = TRUE,
names_repair = "check_unique",
ptype = list(),
transform = list()
)
unnest_auto(data, col)
}
\arguments{
\item{.data, data}{A data frame.}
\item{.col, col}{List-column to extract components from.}
\item{...}{Components of \code{.col} to turn into columns in the form
\code{col_name = "pluck_specification"}. You can pluck by name with a character
vector, by position with an integer vector, or with a combination of the
two with a list. See \code{\link[purrr:pluck]{purrr::pluck()}} for details.
The column names must be unique in a call to \code{hoist()}, although existing
columns with the same name will be overwritten. When plucking with a
single string you can choose to omit the name, i.e. \code{hoist(df, col, "x")}
is short-hand for \code{hoist(df, col, x = "x")}.}
\item{.remove}{If \code{TRUE}, the default, will remove extracted components
from \code{.col}. This ensures that each value lives only in one place.}
\item{.simplify, simplify}{If \code{TRUE}, will attempt to simplify lists of
length-1 vectors to an atomic vector}
\item{.ptype, ptype}{Optionally, a named list of prototypes declaring the desired
output type of each component. Use this argument if you want to check each
element has the types you expect when simplifying.}
\item{.transform, transform}{Optionally, a named list of transformation functions
applied to each component. Use this function if you want transform or
parse individual elements as they are hoisted.}
\item{values_to}{Name of column to store vector values. Defaults to \code{col}.}
\item{indices_to}{A string giving the name of column which will contain the
inner names or position (if not named) of the values. Defaults to \code{col}
with \verb{_id} suffix}
\item{indices_include}{Add an index column? Defaults to \code{TRUE} when \code{col}
has inner names.}
\item{names_repair}{Used to check that output data frame has valid
names. Must be one of the following options:
\itemize{
\item "minimal": no name repair or checks, beyond basic existence,
\item "unique": make sure names are unique and not empty,
\item "check_unique": (the default), no name repair, but check they are unique,
\item "universal": make the names unique and syntactic
\item a function: apply custom name repair.
\item \link{tidyr_legacy}: use the name repair from tidyr 0.8.
\item a formula: a purrr-style anonymous function (see \code{\link[rlang:as_function]{rlang::as_function()}})
}
See \code{\link[vctrs:vec_as_names]{vctrs::vec_as_names()}} for more details on these terms and the
strategies used to enforce them.}
\item{names_sep}{If \code{NULL}, the default, the names will be left
as is. If a string, the inner and outer names will be paste together using
\code{names_sep} as a separator.}
}
\description{
\code{hoist()}, \code{unnest_longer()}, and \code{unnest_wider()} provide tools for
rectangling, collapsing deeply nested lists into regular columns.
\code{hoist()} allows you to selectively pull components of a list-column out
in to their own top-level columns, using the same syntax as \code{\link[purrr:pluck]{purrr::pluck()}}.
\code{unnest_wider()} turns each element of a list-column into a column, and
\code{unnest_longer()} turns each element of a list-column into a row.
\code{unnest_auto()} picks between \code{unnest_wider()} or \code{unnest_longer()}
based heuristics described below.
Learn more in \code{vignette("rectangle")}.
}
\section{Unnest variants}{
The three \code{unnest()} functions differ in how they change the shape of the
output data frame:
\itemize{
\item \code{unnest_wider()} preserves the rows, but changes the columns.
\item \code{unnest_longer()} preserves the columns, but changes the rows
\item \code{unnest()} can change both rows and columns.
}
These principles guide their behaviour when they are called with a
non-primary data type. For example, if you \code{unnest_wider()} a list of data
frames, the number of rows must be preserved, so each column is turned into
a list column of length one. Or if you \code{unnest_longer()} a list of data
frame, the number of columns must be preserved so it creates a packed
column. I'm not sure how if these behaviours are useful in practice, but
they are theoretically pleasing.
}
\section{\code{unnest_auto()} heuristics}{
\code{unnest_auto()} inspects the inner names of the list-col:
\itemize{
\item If all elements are unnamed, it uses \code{unnest_longer()}
\item If all elements are named, and there's at least one name in
common acros all components, it uses \code{unnest_wider()}
\item Otherwise, it falls back to \code{unnest_longer(indices_include = TRUE)}.
}
}
\examples{
df <- tibble(
character = c("Toothless", "Dory"),
metadata = list(
list(
species = "dragon",
color = "black",
films = c(
"How to Train Your Dragon",
"How to Train Your Dragon 2",
"How to Train Your Dragon: The Hidden World"
)
),
list(
species = "blue tang",
color = "blue",
films = c("Finding Nemo", "Finding Dory")
)
)
)
df
# Turn all components of metadata into columns
df \%>\% unnest_wider(metadata)
# Extract only specified components
df \%>\% hoist(metadata,
"species",
first_film = list("films", 1L),
third_film = list("films", 3L)
)
df \%>\%
unnest_wider(metadata) \%>\%
unnest_longer(films)
# unnest_longer() is useful when each component of the list should
# form a row
df <- tibble(
x = 1:3,
y = list(NULL, 1:3, 4:5)
)
df \%>\% unnest_longer(y)
# Automatically creates names if widening
df \%>\% unnest_wider(y)
# But you'll usually want to provide names_sep:
df \%>\% unnest_wider(y, names_sep = "_")
# And similarly if the vectors are named
df <- tibble(
x = 1:2,
y = list(c(a = 1, b = 2), c(a = 10, b = 11, c = 12))
)
df \%>\% unnest_wider(y)
df \%>\% unnest_longer(y)
}