Search code examples
rtidyrnse

How to use nesting_ in SE case


I am struggling to learn how to program using the hadleyverse. I've read the NSE and lazyeval vignettes, but I'm still lost...

I'm trying to translate the example given on the tidyr::complete help page to an SE case.

df <- data_frame(
  group = c(1:2, 1),
  item_id = c(1:2, 2),
  item_name = c("a", "b", "b"),
  value1 = 1:3,
  value2 = 4:6
)
df %>% complete(group, nesting(item_id, item_name))

My ultimate goal is to be able to do the same thing with my variables specified as:

v1 <- 'group'
v2 <- 'item_id, item_name'

But before I try that, I need to be able to work it out using column names directly. To get started, even though I know it's not what I want, this at least doesn't throw an error:

df %>% complete_(list(~group, ~item_id, ~item_name))

What I can't figure out is how to include the 'nesting_'
Things I've tried:

df %>% complete_(~group, nesting_(~item_id, ~item_name)) 
# Error in nesting_(~item_id, ~item_name) : unused argument (~item_name)

df %>% complete_(~group, nesting_(list(~item_id, ~item_name)))
# Error: Each variable must be named. 
# Problem variables: 1, 2 

df %>% complete_(~group, nesting_(alist(~item_id, ~item_name)))
# Error: Each variable must be named. 
# Problem variables: 1, 2 

df %>% complete_(~group, nesting_(list('item_id' = item_id, 'item_name' = item_name)))
# Error in stopifnot(is.list(x)) : object 'item_id' not found

df %>% complete_(~group, nesting_(list('item_id' = df$item_id, 'item_name' = df$item_name)))
# No syntax error, but doesn't expand...

df %>% complete_(~group, nesting_(named_dots(item_id, item_name)))
# Error: Each variable must be a 1d atomic vector or list.
# Problem variables: 'item_id', 'item_name'

df %>% complete_(~group, nesting_(list('item_id' = item_id, 'item_name' = item_name)))
# Error in stopifnot(is.list(x)) : object 'item_id' not found

df %>% complete_(~group, nesting_(list(as.name(item_id), as.name(item_name))))
# Error in as.name(item_id) : object 'item_id' not found

df %>% complete_(~group, nesting_(as.name(item_id), as.name(item_name)))
# Error in nesting_(as.name(item_id), as.name(item_name)) : 
#   unused argument (as.name(item_name))

Thanks for any help!!


Solution

  • I got complete_ and nesting_ to work together like this:

    df %>% complete_(list(~group, ~nesting_(list(item_id = item_id, item_name = item_name))))
    

    Looking at the code for nesting_, it looks like named list comes from the use of tibble::as_data_frame.

    However, the code above doesn't help much when you actually start using your named variables. Things still work with complete_ OK:

    df %>% complete_(list(as.name(v1), ~nesting_(list(item_id = item_id, item_name = item_name))))
    

    And you can make the named list for nesting_ via setNames and a vector of the names:

    v2 <- c("item_id", "item_name")
    df %>% complete_(list(as.name(v1), ~nesting_(setNames(list(item_id, item_name), v2))))
    

    But I didn't find a solution to work with the list of names for nesting_. My failures involved things like

    df %>% complete_(list(as.name(v1), ~nesting_(setNames(lapply(v2, as.name), v2))))
    

    Error: Each variable must be a 1d atomic vector or list. Problem variables: 'item_id', 'item_name'

    I didn't try much beyond that, but it may give you a starting point.