#r #dplyr #data.table
Вопрос:
Я переключаю множество своих конвейеров обработки данных с dplyr на data.table из-за повышения производительности. Мне нравится лаконичность a[b]
синтаксиса соединений. dplyr::left_join(x, y)
соответствует y[x]
в. data.table
Однако порядок столбцов в обоих случаях разный. Есть ли способ воспроизвести порядок столбцов , который вы получаете из dplyr left_join
, где новые столбцы y
добавляются в правую часть x
, используя y[x]
синтаксис data.table? Я знаю, что вы можете использовать merge(x, y, all.x = TRUE)
, но мне было любопытно, может ли этот []
способ достичь того же результата.
пример
library(dplyr)
library(data.table)
x <- iris
y <- data.frame(Species = c('setosa', 'virginica'), foo = c(100, 200))
j1 <- left_join(x, y)
setDT(x)
setDT(y)
j2 <- y[x, on = 'Species']
j3 <- merge(x, y, all.x = TRUE)
Как мне сделать j2
так, чтобы порядок столбцов был таким же, как j1
и и j3
?
> head(j1, 1)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species foo
1: 5.1 3.5 1.4 0.2 setosa 100
> head(j2, 1)
Species foo Sepal.Length Sepal.Width Petal.Length Petal.Width
1: setosa 100 5.1 3.5 1.4 0.2
> head(j3, 1)
Species Sepal.Length Sepal.Width Petal.Length Petal.Width foo
1: setosa 5.1 3.5 1.4 0.2 100
Ответ №1:
Мы можем выполнить задание ( :=
), которое было бы более эффективным, как это делается по ссылке
j2 <- copy(x)
j2[y, foo := foo, on = .(Species)]
-тестирование
all.equal(j1, type.convert(as.data.frame(j2), as.is = TRUE))
#[1] TRUE
Комментарии:
1. Если есть несколько столбцов,
y
отличных от столбца, к которому мы присоединяемся, не потребуется ли для этого назначить их все:=
?2. @qdread Если их больше, например, foo1,
nm1 <- names(y)[3:5]
foo2 и т.д. , Тоj2[y, (nm1) := mget(nm1), on = .(Species)]
3. Или, если это все столбцы, кроме «Видов»,
nm1 <- setdiff(names(y), 'Species')
а затем примените тот же код4. Это хороший ответ, но в конце концов я думаю, что код в конечном итоге будет более подробным, чем
merge()
способ, так что я могу просто придерживаться этого!5. @qdread Я бы сказал
:=
, что должно быть быстрее