Eşleştirme yaklaşımı, birinci veri çerçevesinde her bir anahtar değer için ikinci veri çerçevesinde benzersiz bir anahtar olduğunda çalışır. İkinci veri çerçevesinde kopyalar varsa, eşleştirme ve birleştirme yaklaşımları aynı değildir. Maç, elbette daha hızlıdır çünkü o kadar başarılı değildir. Özellikle, yinelenen anahtarları asla aramaz. (koddan sonra devam)
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
Soruya gönderilen sqldf kodunda, iki tabloda indeksler kullanılmış gibi görünebilir, ancak aslında, sql select çalıştırılmadan önce üzerine yazılan tablolara yerleştirilir ve kısmen nedenini açıklar. çok yavaş. Sqldf fikri, R oturumunuzdaki veri çerçevelerinin sqlite'daki tabloları değil, veri tabanını oluşturmasıdır. Bu nedenle, kod nitelenmemiş bir tablo adına her atıfta bulunduğunda, bunun için R çalışma alanınıza bakacaktır - sqlite'ın ana veritabanına değil. Böylece gösterilen select deyimi çalışma alanından d1 ve d2'yi sqlite'ın ana veritabanına okur ve indekslerle orada bulunanları bozar. Sonuç olarak, indeks içermeyen bir birleştirme yapar. Eğer sqlite'ın ana veritabanında bulunan d1 ve d2 sürümlerini kullanmak istiyorsanız, bunlara main.d1 ve main olarak başvurmanız gerekir. d2 ve d1 ve d2 olarak değil. Ayrıca, olabildiğince hızlı çalışmasını sağlamaya çalışıyorsanız, basit bir birleştirmenin her iki tablodaki dizinlerden yararlanamayacağını ve böylece dizinlerden birini oluştururken zamandan tasarruf edebileceğinizi unutmayın. Aşağıdaki kodda bu noktaları gösteriyoruz.
Kesin hesaplamanın hangi paketin en hızlı olduğu konusunda büyük bir fark yaratabileceğini fark etmek önemlidir. Örneğin, aşağıda bir birleştirme ve bir toplama yapıyoruz. İkisi için sonuçların neredeyse tersine döndüğünü görüyoruz. İlk örnekte en hızlıdan en yavaşa şunu elde ederiz: data.table, plyr, merge ve sqldf, oysa ikinci örnekte sqldf, aggregate, data.table ve plyr - neredeyse ilkinin tersi. İlk örnekte sqldf, data.table'dan 3 kat daha yavaştır ve ikincisinde, plyr'den 200 kat daha hızlı ve data.table'dan 100 kat daha hızlıdır. Aşağıda giriş kodunu, birleştirme için çıkış zamanlamalarını ve toplam için çıkış zamanlamalarını gösteriyoruz. Ayrıca, sqldf'nin bir veritabanına dayandığını ve bu nedenle R'nin işleyebileceğinden daha büyük nesneleri işleyebileceğini (sqldf'nin dbname argümanını kullanırsanız), diğer yaklaşımların ana bellekte işlemeyle sınırlı olduğunu belirtmek de önemlidir. Ayrıca sqldf'yi sqlite ile gösterdik ama aynı zamanda H2 ve PostgreSQL veritabanlarını da destekliyor.
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"))
)
Birleştirme hesaplamalarını karşılaştıran iki kıyaslama çağrısının çıktıları şunlardır:
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
Toplu hesaplamaları karşılaştıran karşılaştırma çağrısının çıktıları:
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