मैच दृष्टिकोण तब काम करता है जब पहले में प्रत्येक कुंजी मान के लिए दूसरे डेटा फ़्रेम में एक अद्वितीय कुंजी होती है। यदि दूसरे डेटा फ्रेम में डुप्लिकेट हैं तो मैच और मर्ज दृष्टिकोण समान नहीं हैं। मैच, निश्चित रूप से, तेज है क्योंकि यह उतना नहीं कर रहा है। विशेष रूप से यह डुप्लिकेट कुंजी के लिए कभी नहीं दिखता है। (कोड के बाद जारी)
DF1 = data.frame(a = c(1, 1, 2, 2), b = 1:4)
DF2 = data.frame(b = c(1, 2, 3, 3, 4), c = letters[1:5])
merge(DF1, DF2)
b a c
1 1 1 a
2 2 1 b
3 3 2 c
4 3 2 d
5 4 2 e
DF1$c = DF2$c[match(DF1$b, DF2$b)]
DF1$c
[1] a b c e
Levels: a b c d e
> DF1
a b c
1 1 1 a
2 1 2 b
3 2 3 c
4 2 4 e
प्रश्न में पोस्ट किए गए sqldf कोड में, ऐसा प्रतीत हो सकता है कि अनुक्रमणिका का उपयोग दो तालिकाओं पर किया गया था, लेकिन वास्तव में, उन्हें उन तालिकाओं पर रखा गया है जिन्हें sql का चयन करने से पहले कभी भी लिखा गया था और भाग में, क्यों के लिए खाते हैं यह इतना धीमा है। Sqldf का विचार यह है कि आपके R सत्र में डेटा फ़्रेम डेटा बेस का निर्माण करता है, न कि sqlite में तालिकाएँ। इस प्रकार हर बार कोड एक अयोग्य तालिका के नाम को संदर्भित करता है जो आपके आर कार्यक्षेत्र में इसके लिए दिखेगा - न कि साइक्लाइट के मुख्य डेटाबेस में। इस प्रकार जो चुनिंदा कथन दिखाया गया था, वह कार्यक्षेत्र से d1 और d2 को sqlite के मुख्य डेटाबेस में शामिल करता है जो कि अनुक्रमणिका के साथ थे। परिणामस्वरूप यह बिना किसी इंडेक्स के साथ जुड़ता है। यदि आप d1 और d2 के संस्करणों का उपयोग करना चाहते थे, जो कि sqlite के मुख्य डेटाबेस में थे, तो आपको उन्हें main.d1 और main के रूप में संदर्भित करना होगा। d2 और d1 और d2 के रूप में नहीं। इसके अलावा, यदि आप इसे अधिक से अधिक तेजी से चलाने की कोशिश कर रहे हैं, तो ध्यान दें कि एक साधारण जोड़ दोनों तालिकाओं पर अनुक्रमित का उपयोग नहीं कर सकता है ताकि आप अनुक्रमित में से एक बनाने का समय बचा सकें। नीचे दिए गए कोड में हम इन बिंदुओं को चित्रित करते हैं।
यह ध्यान देने योग्य है कि सटीक गणना किस पैकेज पर सबसे तेज़ है, इससे बहुत अंतर हो सकता है। उदाहरण के लिए, हम नीचे एक मर्ज और एक समुच्चय करते हैं। हम देखते हैं कि परिणाम दोनों के लिए लगभग उलट हैं। पहले उदाहरण में सबसे तेज़ से सबसे धीमी गति से हम प्राप्त करते हैं: data.table, plyr, मर्ज और sqldf जबकि दूसरे उदाहरण में sqldf, समुच्चय, data.table और plyr - लगभग पहले वाले के विपरीत। पहले उदाहरण में sqldf data.table से 3x धीमा है और दूसरे में इसका 200x plyr से तेज और data.table से 100 गुना तेज है। नीचे हम इनपुट कोड दिखाते हैं, मर्ज के लिए आउटपुट टाइमिंग और एग्रीगेट के लिए आउटपुट टाइमिंग। यह भी ध्यान देने योग्य है कि sqldf एक डेटाबेस पर आधारित है और इसलिए R से बड़ी वस्तुओं को संभाल सकता है (यदि आप sqldf के dbname तर्क का उपयोग करते हैं) जबकि अन्य दृष्टिकोण मुख्य मेमोरी में प्रसंस्करण तक सीमित हैं। इसके अलावा हमने sqlite के साथ sqldf को चित्रित किया है लेकिन यह H2 और PostgreSQL डेटाबेस का भी समर्थन करता है।
library(plyr)
library(data.table)
library(sqldf)
set.seed(123)
N <- 1e5
d1 <- data.frame(x=sample(N,N), y1=rnorm(N))
d2 <- data.frame(x=sample(N,N), y2=rnorm(N))
g1 <- sample(1:1000, N, replace = TRUE)
g2<- sample(1:1000, N, replace = TRUE)
d <- data.frame(d1, g1, g2)
library(rbenchmark)
benchmark(replications = 1, order = "elapsed",
merge = merge(d1, d2),
plyr = join(d1, d2),
data.table = {
dt1 <- data.table(d1, key = "x")
dt2 <- data.table(d2, key = "x")
data.frame( dt1[dt2,list(x,y1,y2=dt2$y2)] )
},
sqldf = sqldf(c("create index ix1 on d1(x)",
"select * from main.d1 join d2 using(x)"))
)
set.seed(123)
N <- 1e5
g1 <- sample(1:1000, N, replace = TRUE)
g2<- sample(1:1000, N, replace = TRUE)
d <- data.frame(x=sample(N,N), y=rnorm(N), g1, g2)
benchmark(replications = 1, order = "elapsed",
aggregate = aggregate(d[c("x", "y")], d[c("g1", "g2")], mean),
data.table = {
dt <- data.table(d, key = "g1,g2")
dt[, colMeans(cbind(x, y)), by = "g1,g2"]
},
plyr = ddply(d, .(g1, g2), summarise, avx = mean(x), avy=mean(y)),
sqldf = sqldf(c("create index ix on d(g1, g2)",
"select g1, g2, avg(x), avg(y) from main.d group by g1, g2"))
)
मर्ज गणना की तुलना में दो बेंचमार्क कॉल से आउटपुट हैं:
Joining by: x
test replications elapsed relative user.self sys.self user.child sys.child
3 data.table 1 0.34 1.000000 0.31 0.01 NA NA
2 plyr 1 0.44 1.294118 0.39 0.02 NA NA
1 merge 1 1.17 3.441176 1.10 0.04 NA NA
4 sqldf 1 3.34 9.823529 3.24 0.04 NA NA
कुल गणना की तुलना बेंचमार्क कॉल से आउटपुट हैं:
test replications elapsed relative user.self sys.self user.child sys.child
4 sqldf 1 2.81 1.000000 2.73 0.02 NA NA
1 aggregate 1 14.89 5.298932 14.89 0.00 NA NA
2 data.table 1 132.46 47.138790 131.70 0.08 NA NA
3 plyr 1 212.69 75.690391 211.57 0.56 NA NA