Подход совпадения работает, когда во втором фрейме данных есть уникальный ключ для каждого значения ключа в первом.Если во втором фрейме данных есть дубликаты, то подходы совпадения и слияния не совпадают.Матч, конечно, быстрее, так как он не так много.В частности, он никогда не ищет дубликаты ключей.(продолжение после кода)
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 Select всегда запускается, и это, отчасти, объясняет, почему он так медленно.Идея sqldf состоит в том, что фреймы данных в вашем сеансе R составляют базу данных, а не таблицы в sqlite.Таким образом, каждый раз, когда код ссылается на неквалифицированное имя таблицы, он будет искать его в вашем рабочем пространстве R, а не в основной базе данных sqlite.Таким образом, оператор select, который был показан, считывает d1 и d2 из рабочей области в основную базу данных sqlite, перекрывая те, которые были там с индексами.В результате он выполняет соединение без индексов.Если вы хотите использовать версии d1 и d2, которые были в основной базе данных sqlite, вы должны ссылаться на них как main.d1 и main.d2, а не как d1 и d2.Кроме того, если вы пытаетесь сделать его максимально быстрым, учтите, что простое объединение не может использовать индексы обеих таблиц, поэтому вы можете сэкономить время на создание одного из индексов.В приведенном ниже коде мы иллюстрируем эти моменты.
Стоит заметить, что точное вычисление может иметь огромное значение для наиболее быстрого пакета.Например, мы делаем слияние и совокупность ниже.Мы видим, что результаты почти противоположны для двух.В первом примере от самого быстрого до самого медленного мы получаем: data.table, plyr, merge и sqldf, тогда как во втором примере sqldf, aggregate, data.table и plyr - почти обратное первому.В первом примере sqldf в 3 раза медленнее, чем data.table, а во втором - в 200 раз быстрее, чем plyr, и в 100 раз быстрее, чем data.table.Ниже мы показываем входной код, время выхода для слияния и время выхода для агрегата.Стоит также отметить, что sqldf основан на базе данных и, следовательно, может обрабатывать объекты больше, чем R (если вы используете аргумент dbname в sqldf), тогда как другие подходы ограничены обработкой в основной памяти.Также мы проиллюстрировали sqldf с помощью sqlite, но он также поддерживает базы данных 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"))
)
Выводы из двух тестов сравнения, сравнивающих вычисления слияния, следующие:Результаты бенчмарка, сравнивающего совокупные вычисления:
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