将多行的组合矩阵放在数据帧的列中,然后将其拆分

时间:2017-05-25 16:28:20

标签: r dplyr tidyr

我有一个看起来像这样的数据框(我简化):

df <- data.frame(rbind(c(1, "dog", "cat", "rabbit"), c(2, "apple", "peach", "cucumber")))
colnames(df) <- c("ID", "V1", "V2", "V3")

##   ID    V1    V2       V3
## 1  1   dog   cat   rabbit
## 2  2 apple peach cucumber

我想创建一个包含变量V1:V3的所有可能组合的列,两个两个(顺序并不重要),但保留与原始ID的链接。就像这样。

##    ID  bigrams
## 1   1    dog cat
## 2   1    cat rabbit
## 3   1    dog rabbit
## 4   2    apple peach
## 5   2    apple cucumber
## 6   2    peach cucumber

我的想法:使用combn()mutate()separate_row()

library(tidyr)
library(dplyr)

df %>% 
mutate(bigrams=paste(unlist(t(combn(df[,2:4],2))), collapse="-")) %>% 
separate_rows(bigrams, sep="-") %>% 
select(ID,bigrams)

结果不是我的预期...我猜连接矩阵(combine()的结果)并不那么容易。

我有两个问题:1)如何调试此代码? 2)这是做这种事情的好方法吗?我是R的新手,但我有一个Open Refine背景,所以连接分割的多值单元对我来说很有意义。但这也是R的正确方法吗?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我们可以使用data.table执行此操作。将'data.frame'转换为'data.table'(setDT(df)),将melt转换为'long'格式,按'ID'分组,获取'{1}}的'value'和combn一起

paste

答案 1 :(得分:1)

我首先推荐@ akrun&#34; melt&#34;方法,但只是为了好玩,这里有更多的方法:

library(tidyverse)
df %>% 
  mutate_all(as.character) %>% 
  transmute(ID = ID, bigrams = pmap(
    list(V1, V2, V3), 
    function(a, b, c) combn(c(a, b, c), 2, paste, collapse = " ")
  ))
#   ID                                     bigrams
# 1  1             dog cat, dog rabbit, cat rabbit
# 2  2 apple peach, apple cucumber, peach cucumber

mutate_all(as.character)只是因为你给了我们因素,而且角色转换的因素可能会令人惊讶。

df %>% 
  mutate_all(as.character) %>%
  nest(-ID) %>% 
  mutate(bigrams = map(data, combn, 2, paste, collapse = " ")) %>%
  unnest(data) %>% 
  as.data.frame()
#   ID                                     bigrams    V1    V2       V3
# 1  1             dog cat, dog rabbit, cat rabbit   dog   cat   rabbit
# 2  2 apple peach, apple cucumber, peach cucumber apple peach cucumber

as.data.frame()只是为了更漂亮的印刷)