您可以使用tidyr::nest,但之后您可能希望将嵌套数据帧简化为字符向量,例如
library(tidyverse)
items <- tibble(name1 = c("Item1", "Item2"),
name2 = c("ItemID1", "ItemID2"),
imgID = c("Img1", "Img2"),
attr1 = c("water", "cocoa"),
attr2 = c("chocolate", "spice"),
attr3 = c("soy", "milk"))
items_nested <- items %>%
nest(contains('attr'), .key = 'attr') %>%
mutate(attr = map(attr, simplify))
items_nested
#> # A tibble: 2 x 4
#> name1 name2 imgID attr
#> <chr> <chr> <chr> <list>
#> 1 Item1 ItemID1 Img1 <chr [3]>
#> 2 Item2 ItemID2 Img2 <chr [3]>
其他选项包括使用 tidyr::gather 将其重新整形为 long,按除新列之外的所有列进行分组,以及以更注重 dplyr 的样式将 value 列聚合到列表中:
items %>%
gather(attr_num, attr, contains('attr')) %>%
group_by_at(vars(-attr_num, -attr)) %>%
summarise(attr = list(attr)) %>%
ungroup()
或uniteattr* 列,然后以更注重字符串的样式将它们分隔在一个列表列中,strsplit:
items %>%
unite(attr, contains('attr')) %>%
mutate(attr = strsplit(attr, '_'))
或以列表为中心的样式使用purrr::transpose 和 tidyselect:
items %>%
mutate(attr = transpose(select(., contains('attr')))) %>%
select(-matches('attr.'))
所有选项都返回相同的东西,至少在样本数据上是这样。进一步清理,例如删除 NAs,可以通过使用 lapply/purrr::map 遍历新列来完成。