expand() is often useful in conjunction with left_join if you want to convert implicit missing values to explicit missing values. Or you can use it in conjunction with anti_join() to figure out which combinations are missing.

expand(data, ...)

crossing(...)

crossing_(x)

nesting(...)

nesting_(x)

Arguments

data

A data frame

...

Specification of columns to expand.

To find all unique combinations of x, y and z, including those not found in the data, supply each variable as a separate argument. To find only the combinations that occur in the data, use nest: expand(df, nesting(x, y, z)).

You can combine the two forms. For example, expand(df, nesting(school_id, student_id), date) would produce a row for every student for each date.

For factors, the full set of levels (not just those that appear in the data) are used. For continuous variables, you may need to fill in values that don't appear in the data: to do so use expressions like year = 2010:2020 or year = full_seq(year).

Length-zero (empty) elements are automatically dropped.

x

For nesting_ and crossing_ a list of variables.

Details

crossing() is similar to expand.grid(), this never converts strings to factors, returns a tbl_df without additional attributes, and first factors vary slowest. nesting() is the complement to crossing(): it only keeps combinations of all variables that appear in the data.

See also

complete for a common application of expand: completing a data frame with missing combinations. expand_ for a version that uses regular evaluation and is suitable for programming with.

Examples

library(dplyr) # All possible combinations of vs & cyl, even those that aren't # present in the data expand(mtcars, vs, cyl)
#> # A tibble: 6 × 2 #> vs cyl #> <dbl> <dbl> #> 1 0 4 #> 2 0 6 #> 3 0 8 #> 4 1 4 #> 5 1 6 #> 6 1 8
# Only combinations of vs and cyl that appear in the data expand(mtcars, nesting(vs, cyl))
#> # A tibble: 5 × 2 #> vs cyl #> <dbl> <dbl> #> 1 0 4 #> 2 0 6 #> 3 0 8 #> 4 1 4 #> 5 1 6
# Implicit missings --------------------------------------------------------- df <- data_frame( year = c(2010, 2010, 2010, 2010, 2012, 2012, 2012), qtr = c( 1, 2, 3, 4, 1, 2, 3), return = rnorm(7) ) df %>% expand(year, qtr)
#> # A tibble: 8 × 2 #> year qtr #> <dbl> <dbl> #> 1 2010 1 #> 2 2010 2 #> 3 2010 3 #> 4 2010 4 #> 5 2012 1 #> 6 2012 2 #> 7 2012 3 #> 8 2012 4
df %>% expand(year = 2010:2012, qtr)
#> # A tibble: 12 × 2 #> year qtr #> <int> <dbl> #> 1 2010 1 #> 2 2010 2 #> 3 2010 3 #> 4 2010 4 #> 5 2011 1 #> 6 2011 2 #> 7 2011 3 #> 8 2011 4 #> 9 2012 1 #> 10 2012 2 #> 11 2012 3 #> 12 2012 4
df %>% expand(year = full_seq(year, 1), qtr)
#> # A tibble: 12 × 2 #> year qtr #> <dbl> <dbl> #> 1 2010 1 #> 2 2010 2 #> 3 2010 3 #> 4 2010 4 #> 5 2011 1 #> 6 2011 2 #> 7 2011 3 #> 8 2011 4 #> 9 2012 1 #> 10 2012 2 #> 11 2012 3 #> 12 2012 4
df %>% complete(year = full_seq(year, 1), qtr)
#> # A tibble: 12 × 3 #> year qtr return #> <dbl> <dbl> <dbl> #> 1 2010 1 -1.400043517 #> 2 2010 2 0.255317055 #> 3 2010 3 -2.437263611 #> 4 2010 4 -0.005571287 #> 5 2011 1 NA #> 6 2011 2 NA #> 7 2011 3 NA #> 8 2011 4 NA #> 9 2012 1 0.621552721 #> 10 2012 2 1.148411606 #> 11 2012 3 -1.821817661 #> 12 2012 4 NA
# Nesting ------------------------------------------------------------------- # Each person was given one of two treatments, repeated three times # But some of the replications haven't happened yet, so we have # incomplete data: experiment <- data_frame( name = rep(c("Alex", "Robert", "Sam"), c(3, 2, 1)), trt = rep(c("a", "b", "a"), c(3, 2, 1)), rep = c(1, 2, 3, 1, 2, 1), measurment_1 = runif(6), measurment_2 = runif(6) ) # We can figure out the complete set of data with expand() # Each person only gets one treatment, so we nest name and trt together: all <- experiment %>% expand(nesting(name, trt), rep) all
#> # A tibble: 9 × 3 #> name trt rep #> <chr> <chr> <dbl> #> 1 Alex a 1 #> 2 Alex a 2 #> 3 Alex a 3 #> 4 Robert b 1 #> 5 Robert b 2 #> 6 Robert b 3 #> 7 Sam a 1 #> 8 Sam a 2 #> 9 Sam a 3
# We can use anti_join to figure out which observations are missing all %>% anti_join(experiment)
#> Joining, by = c("name", "trt", "rep")
#> # A tibble: 3 × 3 #> name trt rep #> <chr> <chr> <dbl> #> 1 Sam a 3 #> 2 Sam a 2 #> 3 Robert b 3
# And use right_join to add in the appropriate missing values to the # original data experiment %>% right_join(all)
#> Joining, by = c("name", "trt", "rep")
#> # A tibble: 9 × 5 #> name trt rep measurment_1 measurment_2 #> <chr> <chr> <dbl> <dbl> <dbl> #> 1 Alex a 1 0.40232824 0.2898923 #> 2 Alex a 2 0.19566983 0.6783804 #> 3 Alex a 3 0.40353812 0.7353196 #> 4 Robert b 1 0.06366146 0.1959567 #> 5 Robert b 2 0.38870131 0.9805397 #> 6 Robert b 3 NA NA #> 7 Sam a 1 0.97554784 0.7415215 #> 8 Sam a 2 NA NA #> 9 Sam a 3 NA NA
# Or use the complete() short-hand experiment %>% complete(nesting(name, trt), rep)
#> # A tibble: 9 × 5 #> name trt rep measurment_1 measurment_2 #> <chr> <chr> <dbl> <dbl> <dbl> #> 1 Alex a 1 0.40232824 0.2898923 #> 2 Alex a 2 0.19566983 0.6783804 #> 3 Alex a 3 0.40353812 0.7353196 #> 4 Robert b 1 0.06366146 0.1959567 #> 5 Robert b 2 0.38870131 0.9805397 #> 6 Robert b 3 NA NA #> 7 Sam a 1 0.97554784 0.7415215 #> 8 Sam a 2 NA NA #> 9 Sam a 3 NA NA