A list-based version of unite() and separate(). Creates a list column that contains named lists, instead of a character vector.
Use case:
zip <- function(data, col, ..., remove = TRUE) {
col <- tidyr:::col_name(substitute(col))
from <- dplyr::select_vars(names(data), ...)
zip_(data, col, from, remove = remove)
}
zip_ <- function(data, col, from, remove = TRUE) {
UseMethod("zip_")
}
zip_.data.frame <- function(data, col, from, remove = TRUE) {
united <- lapply(purrr::zip_n(data[from]), setNames, nm = from)
first_col <- which(names(data) %in% from)[1]
data2 <- tidyr:::append_col(data, united, col, after = first_col - 1)
if (remove) {
data2 <- data2[setdiff(names(data2), from)]
}
data2
}
library(tidyr)
library(dplyr)
##
## Attaching package: 'dplyr'
##
## The following objects are masked from 'package:stats':
##
## filter, lag
##
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
data <- expand.grid(c=letters[1:2], d=letters[3:4], key=1:2) %>%
tbl_df %>%
mutate(value1 = 1:8, value2 = LETTERS[1:8])
data
## Source: local data frame [8 x 5]
##
## c d key value1 value2
## (fctr) (fctr) (int) (int) (chr)
## 1 a c 1 1 A
## 2 b c 1 2 B
## 3 a d 1 3 C
## 4 b d 1 4 D
## 5 a c 2 5 E
## 6 b c 2 6 F
## 7 a d 2 7 G
## 8 b d 2 8 H
zipped <- data %>% zip("values", value1, value2)
zipped
## Source: local data frame [8 x 4]
##
## c d key values
## (fctr) (fctr) (int) (chr)
## 1 a c 1 <list[2]>
## 2 b c 1 <list[2]>
## 3 a d 1 <list[2]>
## 4 b d 1 <list[2]>
## 5 a c 2 <list[2]>
## 6 b c 2 <list[2]>
## 7 a d 2 <list[2]>
## 8 b d 2 <list[2]>
zipped$values[[1]]
## $value1
## [1] 1
##
## $value2
## [1] "A"
spread_res <- zipped %>% spread(key, values)
spread_res
## Source: local data frame [4 x 4]
##
## c d 1 2
## (fctr) (fctr) (chr) (chr)
## 1 a c <list[2]> <list[2]>
## 2 a d <list[2]> <list[2]>
## 3 b c <list[2]> <list[2]>
## 4 b d <list[2]> <list[2]>
spread_res[1,]$`1`
## [[1]]
## [[1]]$value1
## [1] 1
##
## [[1]]$value2
## [1] "A"
spread_res[1,]$`2`
## [[1]]
## [[1]]$value1
## [1] 5
##
## [[1]]$value2
## [1] "E"