我有一个看起来像这样的数据框(我简化):
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的正确方法吗?
提前感谢您的帮助。
答案 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()
只是为了更漂亮的印刷)