आर

2015-02-08 5 views
5
में बढ़त सूची बनाना

मैं इस तरह डेटा है:आर

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 

और मैं इसे इस तरह किनारों की एक सूची के रूप में की आवश्यकता होगी: ID1 से आ रही

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

पहले तीन किनारों चौथे, आईडी 2 से, आईडी 3 में कोई किनार नहीं है, इसलिए आईडी 4 से उस और पांचवें से कुछ भी नहीं है। इसे पूरा करने के तरीके पर कोई विचार? पिघल/डाली?

उत्तर

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 (विभाजन (आइटम, डीजी), फ़ंक्शन (x) यदि (लंबाई (x)> = 2) टी (combn (x, 2)) अन्य न्यूल) नोड्स = के रूप में .data.frame (do.call (rbind, lst [! sapply (lst, is.null)]), लेकिन क्या आप कृपया मुझे सलाह दे सकते हैं कि कैसे "साथ ले जाएं" आईडी और कुछ अन्य चर (आयु, लिंग इत्यादि) मूल डीएफ और उन्हें "नोड्स" में कॉलम के रूप में रखते हैं? – ElinaJ

+0

@ElinaJ क्या आप अपने डेटा को नए डेटासेट के साथ अपडेट कर सकते हैं और अपेक्षित परिणाम – akrun

+0

स्पष्ट होने और उत्तरों से मेल खाने के लिए, मैंने एक नया विषय बनाया: http://stackoverflow.com/questions/28449118/creating-edge-list-with -डिशनल-वेरिएबल्स-इन-आर – ElinaJ

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

अच्छा जवाब। :) मुझे आपकी टिप्पणी 'अगर (...) अन्य (...) 'इस हफ्ते या पिछले हफ्ते से संबंधित है। आप सोच रहे थे कि क्यों 'else()' डेटाटेबल समाधान में नहीं था। मुझे याद नहीं है कि कौन सा सवाल था। क्या आपको कारण मिला कि किसी को और() भाग की आवश्यकता क्यों नहीं है? यदि आपके पास जानकारी है, तो मैं इसे जानना चाहूंगा। – jazzurro

+0

@jazzurro मैं 'if' के बारे में सोच रहा था जब आप 'dplyr :: mutate' जैसे ऑपरेशन करना चाहते हैं और आपको' else' के लिए भी मान प्राप्त करना होगा, अन्यथा आपके पास" पर्याप्त "मान नहीं होंगे। इस स्थिति में मैं 'dplyr :: summarise' के समान कुछ कर रहा हूं, इसलिए मुझे 'else' मानों की आवश्यकता नहीं है (मैं वास्तव में उनसे छुटकारा पाना चाहता हूं, इस प्रकार' if')। प्रश्न के समाधान के बाद समाधान (मुझे लगता है) यह है कि ओपी 'अन्य' कथन में 'एनए' चाहता था, और जब 'if'' data.table' वातावरण में चल रहा है और ': =' ऑपरेटर द्वारा निर्धारित किया गया है , यह डिफ़ॉल्ट रूप से 'एनए' उत्पन्न करता है (यदि 'else' प्रदान नहीं किया गया है)। –

+1

स्पष्ट स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। एनए की डिफ़ॉल्ट पीढ़ी कुछ जानना अच्छा है। एक बार फिर, अपना समय लेने के लिए धन्यवाद। – jazzurro

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

आप 'd'' dfPaths%>% group_by (आईडी)%>% फ़िल्टर (एन()> 1)%>% do (data.frame (V1 = combn (as.character ($ आइटम), 2, मज़ा = पेस्ट, पतन = ";"))) ' – akrun

+0

@akrun धन्यवाद - उसे नहीं पता था। – tchakravarty