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

Put the combinations matrix of many rows in a column of a dataframe, then split it

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

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 两两(顺序无关紧要),但保留 link 与原始 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 的正确方法吗?

在此先感谢您的帮助。

我们可以用 data.table 做到这一点。将'data.frame'转'data.table'(setDT(df)),melt转'long'格式,按'ID'分组,得到combn 'value' 和 paste 一起

library(data.table)
dM <- melt(setDT(df), id.var = "ID")[, combn(value, 2, FUN = paste, collapse=' '), ID]
setnames(dM, 2, 'bigrams')[]
#   ID        bigrams
#1:  1        dog cat
#2:  1     dog rabbit
#3:  1     cat rabbit
#4:  2    apple peach
#5:  2 apple cucumber
#6:  2 peach cucumber

我推荐@akrun 的“melt 优先”方法,但为了好玩,这里有更多方法可以做到这一点:

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() 只是为了更漂亮的打印)