R中

2015-02-08 47 views
5
創建邊列表

我的數據是這樣的:R中

ID=c(rep("ID1",3), rep("ID2",2), "ID3", rep("ID4",2)) 
item=c("a","b","c","a","c","a","b","a") 

data.frame(ID,item) 

ID1 a 
ID1 b 
ID1 c 
ID2 a 
ID2 c 
ID3 a 
ID4 b 
ID4 a 

,我會需要它作爲這樣的邊緣的列表:

a;b 
b;c 
a;c 
a;c 
b;a 

前三邊緣從ID1的到來,第四從ID2開始,ID3沒有任何邊緣,因此ID4沒有任何優勢。任何想法如何實現這一目標?融化/投?

回答

3

嘗試

res <- do.call(rbind,with(df, tapply(item, ID, 
     FUN=function(x) if(length(x)>=2) t(combn(x,2))))) 
    paste(res[,1], res[,2], sep=";") 
#[1] "a;b" "a;c" "b;c" "a;c" "b;a" 
+0

謝謝!我使用你以前的版本:lst < - lapply(split(item,DG),function(x)if(length(x)> = 2)t(combn(x,2))else NULL) nodes = as .data.frame(do.call(rbind,lst [!sapply(lst,is.null)])),但是可以請你告訴我如何「攜帶」身份證和一些其他變量(年齡,性別等)原始df並將它們作爲「節點」中的列? – ElinaJ 2015-02-11 07:03:00

+0

@ElinaJ你可以請更新您的文章與新的數據集和預期的結果 – akrun 2015-02-11 07:37:36

+0

爲了清楚和匹配的答案,我做了一個新的話題:http://stackoverflow.com/questions/28449118/creating-edge-list-with -additional-variables-in-r – ElinaJ 2015-02-11 07:55:45

5

我猜應該有一個簡單的igrpah的解決方案,但這裏的使用data.table

library(data.table) 
setDT(df)[, if(.N > 1) combn(as.character(item), 2, paste, collapse = ";"), ID] 

#  ID V1 
# 1: ID1 a;b 
# 2: ID1 a;c 
# 3: ID1 b;c 
# 4: ID2 a;c 
# 5: ID4 b;a 
+0

很好的答案。 :)我記得你本週或上週有關'if(...)else(...)'的評論。你想知道爲什麼'else()'不在data.table解決方案中。我不記得那是什麼問題。你有沒有找到不需要其他()部分的原因?如果你有信息,我想知道它。 – jazzurro 2015-02-08 13:19:45

+0

@jazzurro我想知道如果你想進行諸如'dplyr :: mutate'之類的操作,那麼你也必須獲得'else'的值,否則你不會有足夠的值。在這種情況下,我正在做類似'dplyr :: summarise'的東西,所以我不需要'else'值(我真的想擺脫它們,因此'if')。當時的問題的解決方案(我猜)是OP要求'else'語句中的'NA',以及'if'在'data.table'環境中運行並且由':='運算符確定,它默認生成「NA」(如果未提供「else」)。 – 2015-02-08 13:24:43

+1

非常感謝您的明確解釋。 NA的默認生成是值得了解的。再次感謝您抽出寶貴時間。 – jazzurro 2015-02-08 13:36:38

2

下面是一個使用了一個更加靈活的解決方案的簡單解決方案與其他解決方案相同的核心邏輯:

library(plyr) 
library(dplyr) 

ID=c(rep("ID1",3), rep("ID2",2), "ID3", rep("ID4",2)) 
item=c("a","b","c","a","c","a","b","a") 

dfPaths = data.frame(ID, item) 
dfPaths2 = dfPaths %>% 
    group_by(ID) %>% 
    mutate(numitems = n(), item = as.character(item)) %>% 
    filter(numitems > 1) 


ddply(dfPaths2, .(ID), function(x) t(combn(x$item, 2))) 
+1

你可以在'dplyr'中使用'do''dfPaths%>%group_by(ID)%>%filter(n()> 1)%>%do(data.frame(V1 = combn(as.character 。$ item),2,FUN = paste,collapse =「;」)))' – akrun 2015-02-08 14:19:04

+0

@akrun謝謝 - 不知道。 – tchakravarty 2015-02-08 14:25:02