Skip to content

Instantly share code, notes, and snippets.

@infotroph
Created February 8, 2017 17:49
Show Gist options
  • Save infotroph/937511c33eaa2aaa98a9a321c7d4a2fc to your computer and use it in GitHub Desktop.
Save infotroph/937511c33eaa2aaa98a9a321c7d4a2fc to your computer and use it in GitHub Desktop.
library(dplyr)
badly_behaved_function = function(x)if(x==1){data.frame(a=1:5, b=5:1)}else{list()}
obtained = data.frame(id=1:3) %>% group_by(id) %>% do(res = badly_behaved_function(.$id))
obtained
# Source: local data frame [3 x 2]
# Groups: <by row>
#
# # A tibble: 3 × 2
# id res
# * <int> <list>
# 1 1 <data.frame [5 × 2]>
# 2 2 <list [0]>
# 3 3 <list [0]>
obtained %>% tidyr::unnest()
# Error: Each column must either be a list of vectors or a list of data frames [res]
# Succeeds, but note that IDs 2 and 3 are completely removed
obtained %>% filter(length(res) > 0) %>% tidyr::unnest()
# # A tibble: 5 × 3
# id a b
# <int> <int> <int>
# 1 1 1 5
# 2 1 2 4
# 3 1 3 3
# 4 1 4 2
# 5 1 5 1
@infotroph
Copy link
Author

infotroph commented Feb 8, 2017

Desired output:

# # A tibble: 7 × 3
#     id     a     b
#  <int> <int> <int>
# 1     1     1     5
# 2     1     2     4
# 3     1     3     3
# 4     1     4     2
# 5     1     5     1
# 6     2    NA    NA
# 7     3    NA    NA

@infotroph
Copy link
Author

One approach: Filter and then join the result back onto the full ID list.

> left_join(obtained %>% select(id), obtained %>% filter(length(res) > 0) %>% tidyr::unnest())

Joining, by = "id"
Source: local data frame [7 x 3]
Groups: <by row>

# A tibble: 7 × 3
     id     a     b
  <int> <int> <int>
1     1     1     5
2     1     2     4
3     1     3     3
4     1     4     2
5     1     5     1
6     2    NA    NA
7     3    NA    NA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment