2015-12-18 15 views
5

से एक वर्ग आसन्नता मैट्रिक्स बनाएं, मैं data.table से एक स्क्वायर आसन्नता matrix बनाने की कोशिश कर रहा हूं।डेटा.फ्रेम या डेटा.table

require(data.table) 
require(plyr) 
require(reshape2) 
# Build a mock data.table 
dt <- data.table(Source=as.character(rep(letters[1:3],2)),Target=as.character(rep(letters[4:2],2))) 
dt 
# Source Target 
#1:  a  d 
#2:  b  c 
#3:  c  b 
#4:  a  d 
#5:  b  c 
#6:  c  b 
sry <- ddply(dt, .(Source,Target), summarize, Frequency=length(Source)) 
sry 
# Source Target Frequency 
#1  a  d   2 
#2  b  c   2 
#3  c  b   2 
mtx <- as.matrix(dcast(sry, Source ~ Target, value.var="Frequency", fill=0)) 
rownames(mtx) <- mtx[,1] 
mtx <- mtx[,2:ncol(mtx)] 
mtx 
# b c d 
#a "0" "0" "2" 
#b "0" "2" "0" 
#c "2" "0" "0" 

अब, यह बहुत है कि मैं क्या, प्राप्त करने के लिए, सिवाय इसके कि मैं की तरह, सभी नोड्स दोनों आयामों में प्रतिनिधित्व करना चाहते हैं चाहते हैं के करीब है: यहाँ मैं पहले से ही है की एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण है

a b c d 
a 0 0 0 2 
b 0 0 2 0 
c 0 2 0 0 
d 0 0 0 0 

ध्यान दें कि मैं काफी बड़े डेटा पर काम कर रहा हूं, इसलिए मैं इसके लिए एक कुशल समाधान ढूंढना चाहता हूं।

आपकी मदद के लिए धन्यवाद।


समाधान (संपादित):

की पेशकश की समाधान की गुणवत्ता और मेरे डाटासेट के आकार को देखते हुए, मैं बेंचमार्क सब समाधान।

#The bench was made with a 1-million-row sample from my original dataset 
library(data.table) 
aa <- fread("small2.csv",sep="^") 
dt <- aa[,c(8,9),with=F] 
colnames(dt) <- c("Source","Target") 
dim(dt) 
#[1] 1000001  2 
levs <- unique(unlist(dt, use.names=F)) 
length(levs) 
#[1] 2222 

इस डेटा को देखते हुए, वांछित आउटपुट एक 2222 * 2222 मैट्रिक्स है (2222 * 2223 समाधान जहां पहले कॉलम पंक्ति नाम शामिल भी स्पष्ट रूप से स्वीकार्य हैं)।

# Ananda Mahto's first solution 
am1 <- function() { 
    table(dt[, lapply(.SD, factor, levs)]) 
} 
dim(am1()) 
#[1] 2222 2222 

# Ananda Mahto's second solution 
am2 <- function() { 
    as.matrix(dcast(dt[, lapply(.SD, factor, levs)], Source~Target, drop=F, value.var="Target", fun.aggregate=length)) 
} 
dim(am2()) 
#[1] 2222 2223 

library(dplyr) 
library(tidyr) 
# Akrun's solution 
akr <- function() { 
    dt %>% 
     mutate_each(funs(factor(., levs))) %>% 
     group_by(Source, Target) %>% 
     tally() %>% 
     spread(Target, n, drop=FALSE, fill=0) 
} 
dim(akr()) 
#[1] 2222 2223 

library(igraph) 
# Carlos Cinelli's solution 
cc <- function() { 
    g <- graph_from_data_frame(dt) 
    as_adjacency_matrix(g) 
} 
dim(cc()) 
#[1] 2222 2222 

और बेंचमार्क का नतीजा है ...

library(rbenchmark) 
benchmark(am1(), am2(), akr(), cc(), replications=75) 
# test replications elapsed relative user.self sys.self user.child sys.child 
# 1 am1()   75 15.939 1.000 15.636 0.280   0   0 
# 2 am2()   75 111.558 6.999 109.345 1.616   0   0 
# 3 akr()   75 43.786 2.747 42.463 1.134   0   0 
# 4 cc()   75 46.193 2.898 45.532 0.563   0   0 
+0

'sry' से शुरू करते हुए इस दूसरे प्रश्न से संबंधित है/एक ही http://stackoverflow.com/q/9617348/1191259 – Frank

+1

प्रश्न संबंधित है लेकिन निश्चित रूप से वही नहीं है। मेरे पास पहले से ही ऐसा परिणाम था और इसे प्रदर्शित किया। उस प्रश्न के उदाहरण के डेटा के साथ, मेरा बिंदु आयाम 'सी (" ए "," बी "," सी "," एक्स "," वाई ") के साथ 5x5 मैट्रिक्स प्राप्त करना होगा। – Vongo

उत्तर

6

ऐसा लगता है कि तुम सिर्फ table की तलाश कर रहे हैं, लेकिन आप यकीन है कि दोनों स्तंभ एक ही कारक स्तर है कि बनाना चाहिए:

levs <- unique(unlist(dt, use.names = FALSE)) 
table(lapply(dt, factor, levs)) 
#  Target 
# Source a b c d 
#  a 0 0 0 2 
#  b 0 0 2 0 
#  c 0 2 0 0 
#  d 0 0 0 0 

मुझे नहीं पता कि यह किसी भी गति में सुधार करेगा या नहीं, लेकिन आपका भी उपयोग कर सकते हैं"data.table" से:

dcast(lapply(dt, factor, levs), Source ~ Target, drop = FALSE, 
     value.var = "Target", fun.aggregate = length) 
+0

कमाल। मैं प्रदर्शन भाग की जांच करूंगा और यह समझने की कोशिश करूंगा कि आपके समाधान कैसे काम करते हैं। धन्यवाद! – Vongo

1

हम उपयोग कर सकते हैं dplyr/tidyr

library(dplyr) 
library(tidyr) 
dt %>% 
    mutate_each(funs(factor(., letters[1:4]))) %>% 
    group_by(Source, Target) %>% 
    tally() %>% 
    spread(Target, n, drop=FALSE, fill=0) 
# Source  a  b  c  d 
# (fctr) (dbl) (dbl) (dbl) (dbl) 
#1  a  0  0  0  2 
#2  b  0  0  2  0 
#3  c  0  2  0  0 
#4  d  0  0  0  0 
3

तुम भी igraph उपयोग कर सकते हैं। जब से तुम ने कहा कि आप, बड़े डेटा के साथ काम कर रहे हैं igraph लाभ यह है कि विरल मैट्रिक्स का उपयोग करता है:

library(igraph) 
g <- graph_from_data_frame(dt) 
as_adjacency_matrix(g) 
4 x 4 sparse Matrix of class "dgCMatrix" 
    a b c d 
a . . . 2 
b . . 2 . 
c . 2 . . 
d . . . .