#r #join #data.table #left-join
Вопрос:
Я снова пытаюсь понять, как mult
работает аргумент при выполнении обновления при соединении. То, что я пытаюсь сделать,-это реализовать левое соединение, как определено в жж.
По соображениям производительности я хотел бы обновить левую таблицу
«Нетривиальная» часть заключается в том, что, когда левая таблица и правая таблица имеют общий столбец (не учитывая столбцы объединения), я хотел бы использовать первое значение в правой таблице для переопределения значения левой таблицы. Я думал mult
, что это поможет мне справиться с этой проблемой с несколькими матчами, но я не могу сделать это правильно
library(data.table)
X <- data.table(x = c("a", "a", "b", "c", "d"), y = c(0, 1, 1, 2, 2), t = 0:4)
X
# x y t
# <char> <num> <int>
#1: a 0 0
#2: a 1 1
#3: b 1 2
#4: c 2 3
#5: d 2 4
Y <- data.table(xx = c("f", "b", "c", "c", "e", "a"), y = c(2, NA, 3, 4, 5, 6), u = 2:7)
Y
# xx y u
# <char> <num> <int>
#1: f 2 2
#2: b NA 3
#3: c 3 4
#4: c 4 5
#5: e 5 6
#6: a 6 7
# Expected result
# x y t
# <char> <num> <int>
#1: a 6 0 <= single match on xx == "a" so Y[xx == "a", y] is used
#2: a 6 1 <= single match on xx == "a" so Y[xx == "a", y] is used
#3: b NA 2 <= single match on xx == "b" so Y[xx == "b", y] is used
#4: c 3 3 <= mult match on xx == "c" so Y[xx == "c", y[1L]] is used
#5: d 2 4 <= no xx == "d" in Y so nothing changes
copy(X)[Y, y := i.y, by = .EACHI, on = c(x = "xx"), mult = "first"][]
# x y t
# <char> <num> <int>
#1: a 6 0
#2: a 1 1 <= a should always have the same value ie 6
#3: b NA 2
#4: c 4 3 <= y == 4 is not the first value of y in the Y table
#5: d 2 4
# Using mult = "all" is the closest I get from the right result
copy(X)[Y, y := i.y, by = .EACHI, on = c(x = "xx"), mult = "all"][]
# x y t
# <char> <num> <int>
#1: a 6 0
#2: a 6 1
#3: b NA 2
#4: c 4 3 <= y == 4 is not the first value of y in the Y table
#5: d 2 4
Может ли кто-нибудь объяснить мне, что не так в вышесказанном ?
Я думаю, что я мог бы использовать Y[X, ...]
, чтобы получить то, что я хочу, проблема в том, что X очень велик, и производительность, которую я получаю, намного хуже, используя Y[X, ...]
Ответ №1:
Я хотел бы использовать первое значение в правой таблице, чтобы переопределить значение левой таблицы
Выберите первые значения и обновите их самостоятельно:
X[unique(Y, by="xx", fromLast=FALSE), on=.(x=xx), y := i.y]
x y t
1: a 6 0
2: a 6 1
3: b NA 2
4: c 3 3
5: d 2 4
fromLast=
можно выбрать первую или последнюю строку при отбрасывании дураков.
Как обрабатывается несколько совпадений:
В x[i, mult=]
, если строка i
имеет несколько совпадений, mult
определяет, какие совпадающие строки x
выбраны. Это объясняет результаты, показанные в ОП.
In x[i, v := i.v]
, если несколько строк i
совпадают с одной и той же строкой x
, все соответствующие i-строки записываются в x-строку последовательно, поэтому последняя i-строка получает окончательную запись. Включите подробный вывод, чтобы увидеть, сколько изменений внесено в обновление-в этом случае оно превысит количество строк x (поскольку строки редактируются повторно).:
options(datatable.verbose=TRUE)
data.table(a=1,b=2)[.(a=1, b=3:4), on=.(a), b := i.b][]
# Assigning to 2 row subset of 1 rows
a b
1: 1 4
Комментарии:
1. Спасибо, я видел это на твоем franknarf1.github.io/r-tutorial/_book/tables.html но почему результат изменился, изменив мульт, приводило в замешательство
Ответ №2:
mult всегда равен «последнему» в случае обновления при соединении с :=
Я помню, что это было описано где-то в документации.
Комментарии:
1. В этом случае есть ошибка, как вы можете видеть, изменение mult изменит вывод.
2. Поэтому, пожалуйста, сообщите 🙂