Ответ 1
Я добавил это в список здесь. И, надеюсь, мы сможем доставить, как и планировалось.
Вероятно, причина в том, что by=.EACHI
- это недавняя функция (начиная с версии 1.9.4), но то, что она делает, не является. Позвольте мне объяснить пример. Предположим, что у нас есть два data.tables X
и Y
:
X = data.table(x = c(1,1,1,2,2,5,6), y = 1:7, key = "x")
Y = data.table(x = c(2,6), z = letters[2:1], key = "x")
Мы знаем, что можем присоединиться, выполнив X[Y]
. это похоже на операцию подмножества, но с использованием data.tables
(вместо целых чисел/имен строк или логических значений). Для каждой строки в Y
, взяв столбцы ключей Y
, она находит и возвращает соответствующие совпадающие строки в столбцах X
(+ столбцы в Y
).
X[Y]
# x y z
# 1: 2 4 b
# 2: 2 5 b
# 3: 6 7 a
Теперь позвольте сказать, что для каждой строки из Y
ключевых столбцов (здесь только один ключевой столбец) мы хотели бы получить количество совпадений в X
. В версиях data.table
< 1.9.4, мы можем сделать это, просто указав .N
в j
следующим образом:
# < 1.9.4
X[Y, .N]
# x N
# 1: 2 2
# 2: 6 1
То, что это неявно делает, в присутствии j
, оценивает j-expression
для каждого согласованного результата X
(соответствует строке в Y
). Это вызвано by-without-by или implicit-by, потому что оно как бы скрыто.
Проблема заключалась в том, что это всегда будет выполнять операцию by
. Итак, если бы мы хотели узнать количество строк после объединения, нам нужно было бы сделать: X[Y][ .N]
(или просто nrow(X[Y])
в этом случае). То есть, мы не можем иметь выражение j
в том же вызове, если мы не хотим by-without-by
. В результате, когда мы сделали, например, X[Y, list(z)]
, он оценил list(z)
с помощью by-without-by
и был поэтому немного медленнее.
Кроме того, пользователи data.table
запросили это как явное - см. this и this для большего контекста.
Следовательно, добавлен by=.EACHI
. Теперь, когда мы делаем:
X[Y, .N]
# [1] 3
он делает то, что он должен делать (избегает путаницы). Он возвращает количество строк, полученных в результате соединения.
и
X[Y, .N, by=.EACHI]
оценивает j
-выражение совпадающих строк для каждой строки в Y
(соответствующее значению из столбцов Y
здесь). Было бы проще увидеть это, используя which=TRUE
.
X[.(2), which=TRUE] # [1] 4 5
X[.(6), which=TRUE] # [1] 7
Если мы запустим .N
для каждого, тогда мы должны получить 2,1.
X[Y, .N, by=.EACHI]
# x N
# 1: 2 2
# 2: 6 1
Итак, теперь у нас есть обе функции. Надеюсь, это поможет.