2017-05-25 25 views
1

我有一個數據幀,看起來像這樣(我簡化):把多行的組合矩陣在數據幀的一列,然後把它分解

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的正確方法嗎?

在此先感謝您的幫助。

回答

1

我們可以用data.table來做到這一點。轉換 'data.frame' 到 'data.table'(setDT(df)),melt它 '長' 格式,由 'ID' 進行分組,讓 '價值' 的combnpaste一起

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 
+1

窩! 0_0我知道data.table是一個強大的軟件包,但對我來說總是顯得很複雜,尤其是對於大型數據框而言。我會試着去理解這兩行。非常感謝,@Akrun!我會稍微等一下,但我不明白如何縮短它。 –

+2

在翻譯中的翻譯將是:'df%>%gather(「variable」,「value」,-ID)%>%group_by(ID)%> transmute(bigrams = combn(value,2,paste,collapse = 「」))%>%ungroup()'。這裏沒有附加值,所以我不會將它作爲單獨的答案 –

+0

謝謝,Aurèle!就目前而言,我感覺更加舒適。 –

1

我建議@ 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()只是一個漂亮打印)

+1

非常有趣的解決方案,無疑會在其他情況下保留我。我會詳細檢查它。現在我已經看到了'data.table'和'tidyverse'中的解決方案,我將按照您的建議選擇第一個答案,這個答案越來越短。非常感謝你 ! –

相關問題