В настоящее время, чтобы иметь эквивалент (или нечто подобное) предложению SQL having
, вам нужно сначала написать [.data.table
, используя by
, а затем передать результат в i
Параметр [.data.table
, например:
dt <- data.table(id = rep(1:2, each = 2),
var = c(0.2, 0.5, 1.5, 1.3))
dt[dt[, mean(var) > 1, by = id]$id]
id var
1: 2 1.5
2: 2 1.3
Другой вариант - использовать условный оператор внутри j
, очень мощный, я делаю все время, и пока нет ничего, что текущий синтаксис не позволял бы мне сделать. Однако я считаю, что наличие параметра having
позволит писать гораздо более понятные и читаемые коды. Например, приведенное выше можно записать так:
dt[, if(mean(var) > 1) .SD, by = id]
Я предлагаю что-то вроде:
dt[, .SD, by = id, having = mean(var) > 1]
Идея состоит в том, чтобы иметь выражение, которое всегда возвращает логическое значение длины 1 , которое укажет, нужно ли вычислять j
для текущей группы.
Спасибо,
Мишель
Отличный ФР. Я тоже долго размышлял над этим вариантом использования. Мы можем сделать это без дополнительного аргумента, например:
dt[, .SD[mean(var)>1], by=id]
(Но для скорости потребуется внутренняя оптимизация .SD[.]
— #735.)
Скорее всего, в этом случае мы прибегнем к .I
вместо этого:
dt[dt[, .I[mean(var) > 1], by=id]$V1]
И было бы здорово получить это напрямую (даже лучше, если бы мы могли добиться этого без having
) - может быть, если выражение j
оценивается как логический вектор с 1 столбцом? Просто мысли вслух.
Привет Арун. Спасибо за ответ. Как только будет доступна оптимизация .SD
, это будет просто вопрос «вкуса» с точки зрения того, что понятнее читать между:
dt[, .SD[mean(var)>1], by=id]
и
dt[, .SD, by = id, having = mean(var) > 1]
Несмотря на то, что второй может также быть более привлекательным для людей, пришедших с других языков (в частности, SQL). Но опять же, это может быть только мое мнение. Может быть, я просто слишком много использовал SQL в последнее время (смеется).
Что касается вкусовой части - мне очень не нравится добавлять дополнительный параметр, когда это можно сделать с помощью простого и стандартного синтаксиса (т.е. первый вариант выше).
Любопытный. Я был уверен, что именно вы, скорее всего, это оцените :-) (учитывая, как сильно вы хотели исключить by-without-by, главным образом для улучшения читаемости, особенно для людей, пришедших с других языков, если я правильно помню). Во всяком случае, я знаю, что это два совершенно разных сценария. Я просто хотел поделиться своей точкой зрения:
[.data.table
особо не вредятj
для конкретной группы.Причины, по которым мне не нравились молчание by-without-by и «иметь», на самом деле одни и те же — я не люблю запоминать лишнее, будь то дополнительные параметры или дополнительное странное поведение.
Я бы сказал, что первое выражение, которое вы написали, намного легче читать, потому что вам не нужно продолжать читать строку, а затем обнаруживать, что указан какой-то новый параметр, и вам нужно вернуться к началу предложения и переоценить ваш ментальная модель происходящего.
Что вы думаете о том, чтобы не добавлять аргумент having
к [
, а превратить его в функцию having()
и заставить его работать с аргументом i
, так же, как order()
работает, например:
dt[ having(var > 1), .(var = mean(var)), by = id ]
# would perform below without additional copy:
dt[, .(var = mean(var)), by = id ][ var > 1 ]
having
будет функцией для оценки аргумента в кадре dt
и обеспечения фильтрации для i
.
Я думаю, что этот FR тесно связан с https://github.com/Rdatatable/data.table/issues/1269 «Возврат только групп». Я часто хочу получить группы с некоторым атрибутом и сохранить их в векторе, например my_teams
в этом посте SO . Вот соответствующая строка:
my_teams <- FantasyTeams[, max(table(Team)) <= 3, by=team_no][(V1)]$team_no
# or
my_teams <- FantasyTeams[, if ( max(table(Team)) <= 3 ) 1, by=team_no]$team_no
С FR having
и «Возврат только групп» это может быть что-то вроде
my_teams <- FantasyTeams[, .(), by = team_no, having = { max(table(Team)) <= 3 }]$team_no
Код такой же длинный, но я предпочитаю его, поэтому мне не нужно внимательно читать j
, чтобы понять цель.
Другой пример из SO . Цель состоит в том, чтобы перезаписать столбец Value
столбцом 3L
, если выполняется какое-либо условие на уровне группы:
DT = setDT(structure(list(Ind = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L), ID = c("A",
"A", "A", "A", "B", "B", "B", "B"), RegionStart = c(1L, 101L,
1L, 101L, 1L, 101L, 1L, 101L), RegionEnd = c(100L, 200L, 100L,
200L, 100L, 200L, 100L, 200L), Value = c(3L, 2L, 3L, 2L, 3L,
2L, 5L, 5L), TN = c("N", "N", "T", "T", "N", "N", "T", "T")), .Names = c("Ind",
"ID", "RegionStart", "RegionEnd", "Value", "TN"), row.names = c(NA,
-8L), class = "data.frame"))
# current syntax
DT[, Value := {
fixit = ( Value[TN=="N"] != 3L ) & ( uniqueN(Value) == 1L )
if (fixit) 3L else Value
}, by=.(ID, RegionStart)]
# with "having"
DT[,
Value := 3L
, by=.(ID, RegionStart)
, having={ ( Value[TN=="N"] != 3L ) & ( n_distinct(Value) == 1L ) }]
Помимо, возможно, более приятного синтаксиса, я предполагаю, что способ having=
также может быть более эффективным, поскольку необходимо изменить только подмножество групп по группам. Самый эффективный способ без having=
наверное выглядит так...
myeyes = DT[, .I[ ( Value[TN=="N"] != 3L ) & ( uniqueN(Value) == 1L )], by=.(ID, RegionStart)]$V1
DT[ myeyes, Value := 3L]
# or
mygs = DT[, ( Value[TN=="N"] != 3L ) & ( uniqueN(Value) == 1L ), by=.(ID, RegionStart)][(V1)][, V1 := NULL]
DT[ mygs, Value := 3L, on=names(mygs)]
которые довольно запутаны.
Изменить : И еще один пример для обновления, если/когда эта функция доступна: http://stackoverflow.com/q/36292702
(2016/4/26:) http://stackoverflow.com/q/36869784
(2016/06/16:) http://stackoverflow.com/q/37855013/
Другой пример из SO . Его можно использовать для выбора строго уникальных строк (относится к #1163):
DT = setDT(structure(list(id = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1,
2, 3, 4), dsp = c(5, 6, 7, 8, 6, 6, 7, 8, 5, 6, 9, 8, 5, 6, 7,
NA), status = c(FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE,
TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE)), .Names = c("id",
"dsp", "status"), row.names = c(NA, -16L), class = "data.frame"))
# my current way to select "strictly unique" rows
Bigdt[, .N, by=names(Bigdt)][N == 1][, N := NULL][]
# could be...
Bigdt[, .SD, by=names(Bigdt), having ={.N == 1L}]
Обратите внимание, что Bigdt[, if (.N == 1L) .SD, by=names(Bigdt)]
здесь не работает, так как .SD
пусто. Возможно, этому может помочь #1269.
И еще один из SO: http://stackoverflow.com/q/38272608/ Они хотят выбирать группы на основе материала в последней строке, поэтому having =
состояние здоровья [.N] == "not healthy"
должно это делать.
И еще один простой случай (фильтрация по размеру): http://stackoverflow.com/q/39085450/
И еще один , с антиприсоединением:
ID <- c("A","A","A","B","B","C","D")
Value <- c(0,1,2,0,2,0,0)
df <- data.frame(ID,Value)
library(data.table)
setDT(df)
# use j = max() to get GForce speedup
df[ !df[, max(Value), by=ID][V1 > 0, .(ID, Value = 0)], on=.(ID, Value)]
# do the more standard thing, if j = if (...) x
df[ !df[, if (max(Value) > 0) .(Value = 0), by=ID], on=.(Value, ID) ]
# desired syntax
df[ !df[, .(Value = 0), by=ID, having = max(Value) > 0], on=.(Value, ID) ]
Впрочем, не такой уж и отличный пример.
И еще один с ответом вроде dt[, if(uniqueN(time)==1L) .SD, by=name, .SDcols="time"]
И еще: http://stackoverflow.com/q/43354165/
И еще: http://stackoverflow.com/q/43613087/
Другой (хотя он может быть удален): http://stackoverflow.com/q/43635968/
Другой http://stackoverflow.com/a/43765352/
Другой http://chat.stackoverflow.com/transcript/message/37148860#37148860
Другой https://stackoverflow.com/q/45557011/
Haiyou https://stackoverflow.com/questions/45598397/filter-data-frame-matching-all-values-of-a-vector
Гм май https://stackoverflow.com/a/45721286/
лингвай иге https://stackoverflow.com/a/45820567/
и https://stackoverflow.com/q/46251221/
уно мас https://stackoverflow.com/questions/46307315/show-sequences-that-include-a-variable-in-r
тамбем https://stackoverflow.com/q/46638058/
И другой. Я хочу подмножить мою таблицу данных (myDT) для записей, которых нет в справочной таблице (idDT):
library(data.table)
idDT = data.table(id = 1:3, v = c("A","B","C"))
myDT = data.table(id = 3:4, z = c("gah","egad"))
# my attempt
idDT[myDT, on=.(id), .SD[.N == 0L], by=.EACHI]
# Empty data.table (0 rows) of 2 cols: id,v
# workaround
myDT[, .SD[idDT[.SD, on=.(id), .N == 0, by=.EACHI]$V1]]
# desired notation (with having=)
myDT[, .SD, by = id, having = idDT[.BY, on=.(id), .N]==0L]
Однако это было бы неэффективно, поскольку моя желаемая нотация влечет за собой каждое значение by=, создающее отдельное соединение с idDT. В этом смысле, возможно, это не лучший пример.
mais um https://stackoverflow.com/questions/47765283/r-data-table-group-by-where/47765308?noredirect=1#comment82524998_47765308 может сделать DT[, if (any(status == "A") && !any(status == "B")) .SD, by=id]
или с параметром DT[, .SD, by=id, having = any(status == "A") && !any(status == "B")]
а затем https://stackoverflow.com/a/48669032/ m[, if(isTRUE(any(passed))) .SD, by=id]
должно быть m[by = id, having = isTRUE(any(passed))]
лучший пример https://stackoverflow.com/q/49072250/
Эйн Андерер https://stackoverflow.com/a/49211292/ stock_profile[, sum(Value), by=Pcode, having=any(Location=="A" & NoSales == "Y")][, sum(V1)]
больше мм https://stackoverflow.com/a/49366998/
другой https://stackoverflow.com/a/49919015/
y https://stackoverflow.com/questions/50257643/deleting-rows-in-r-with-value-less-than-x
Моар https://stackoverflow.com/q/54582048
е https://stackoverflow.com/q/56283005
сохранить группы, если .N ==k (также много в цели обмана)
сохранить группы, если они есть (diff (sorted_col)) <= порог https://stackoverflow.com/q/57512417
сохранить, если max (x) < порог https://stackoverflow.com/a/57698641
@eantonya ИМХО, добавление параметра having
действительно облегчит запоминание. Чрезмерная краткость может быть трудной для запоминания. Более того, сделать data.table
более похожим на SQL — неплохая идея.
В разделе часто задаваемых вопросов data.table
:
2.16 Я слышал, что синтаксис data.table аналогичен SQL.
Да : ...
@ywhuofu data.table уже принимает функцию $# order
i
в качестве аргумента i, чего и ожидает пользователь базы R. Точно так же, как мы переводим sql _ORDER_ в i = order(...)
, мы можем сделать с _HAVING_. Это хорошо подходит, так как i
в data.frame используется для подмножества (_having_ — это просто отложенное подмножество после агрегации) или переупорядочивания.
Может это API?
dt <- data.table(id = rep(1:2, each = 2),
var = c(0.2, 0.5, 1.5, 1.3))
dt[having.i(mean(var) > 1, by = id)]
id var
1 2 1.5
2 2 1.3
Я реализовал эту версию, хотя она устанавливает ограничение на использование только оптимизированных функций gforce
, а также некоторых функций, которые не зависят от группировок (например, +
, |
, &
и т. д.). В SQL используются сводные функции, хотя я бы понял, если бы Cdogroups
захотелось поддерживать.
Одно дополнительное замечание. Кажется, что dt[having(var > 3), .(var = mean(x)), by = .(grp)]
будет трудно вписать в текущий код '[.data.table'
. Потребуются некоторые проверки, чтобы убедиться, что синтаксис правильный.
```
п = 1e6
гпс = 1e5
голова_n = 2L
dt = data.table::data.table (x = образец (группы, n, ИСТИНА), y = runif (n))
выражение мин медиана
1 lw[имея.i(.N < 2L | сумма (y) > 11 | медиана (y) < 0,7, by = x)] 114,13 мс 124,98 мс
2 dt[dt[, .I[.N < 2L | сумма(у) > 11 | медиана(y) < 0,7], by = x]$V1] 4000 мс 4000 мс
выражение минимальная медиана itr/sec
mem_alloc gc/sec
n_itr
1 lw[имея.i(.N < 2L, by = x)] 30,2 мс 35,3 мс 27,9 8,02 МБ 3,99 14
2 dt[dt[, .I[.N < 2L], by = x]$V1] 106,1 мс 110,4 мс 8,81 6,13 МБ 10,6 5
Я бы предпочел, чтобы это был добавленный параметр с именем having=
или group_filter=
(или что-то еще, что не зависит от знания SQL, чтобы знать, что он делает).
например, я думаю, что было бы запутанно объединять фильтры строк в i
с фильтрами на уровне группы также в i
Будет ли having =
работать с подмножеством данных или вы сможете использовать только аргумент i
или аргумент having
? Я также предполагаю, что having
произойдет до оценки j
. Как .BY
и .GRP
, а вскоре и .NGRP
будут работать с ```having = ````?
Синтаксических вариантов не так много:
having
i
, j
, by
.Если необходимы и фильтр строк, и групповой фильтр, dt[row_selector & group_selector, ...]
выглядит неправильно, поэтому кажется, что в таком случае фильтр строк и групповой фильтр не должны появляться в одном и том же аргументе. Тогда i
исключается.
Тогда не будет много вариантов синтаксиса.
Использование by
может привести к путанице. Например,
dt[, .SD, by = having(.(id), mean(var > 1))]
dt[, .SD, by = id ~ mean(var) > 1]
Добавление специальной функции к j
выглядит не очень хорошо.
dt[, having(mean(var) > 1, .SD), by = id]
Теперь код, который мне кажется лучше всего, является самой оригинальной версией.
dt[, if (mean(var) > 1) .SD, by = id]
dt[, if (mean(var) > 1) .(x = sum(x), y = sum(y)), by = id]
Чего я действительно хочу, так это сохранить оптимизацию после групповой фильтрации. Можем ли мы обнаружить выражение if
в j
и оптимизировать его, например, сохранить работу GForce внутри оператора if?
@renkun-ken Или перегрузить другой инфиксный оператор?
dt[, mean(var) > 1 ? .SD, by=id]
Одним из преимуществ специального символа перед if
является то, что пользователь не может поставить соответствующий символ else
позже.
@franknarf1 Кажется, что пока мы пытаемся обнаружить if
в j
, мы также можем проверить, что if
имеет else if
и else
. Мы могли бы оптимизировать только случай if
и оставить if-else
неоптимизированным. Возможно, позже мы сможем справиться и с делом if-else
. Лично я по-прежнему предпочитаю оптимизировать код переопределению или чрезмерному использованию существующих операторов.
@ franknarf1 , это классный синтаксис C, хотя не уверен, что здесь это не сильно усложнит.
var > 1 ? d : e
тоже может работать, не так ли?
var > 1 ? d : e
выглядит лаконично, но работает только для встроенного простого случая, поскольку d
и e
могут быть чем-то вроде {...}
, а приоритет операций может сбивать с толку. Мы только пытаемся разрешить .SD
выполнять чистую групповую фильтрацию или любое выражение в j
здесь?
Добавление синтаксиса имеет проблему, которую пользователь должен знать, что синтаксис обрабатывается особым образом и не должен работать внутри j
. Например, пользователь может ожидать
dt[, mean(var) > 1 ? 0 : (sd(var) < 1 ? 1 : 0), by = id]
работать и даже
dt[, mean(var) > 1 ? 0 : 1]
dt[, mean(var) > 1 ? 0 : (sd(var) < 1 ? 1 : 0)]
вообще работать.
Я немного смущен здесь.
Делает
dt[, .SD, by = id, having = mean(var) > 1]
иметь какое-либо преимущество перед
dt[, if(mean(var) > 1) .SD, by = id]
поскольку mean(var) > 1
всегда будет оцениваться для каждой группы. Служит ли он только синтаксическим сахаром, или мы пытаемся как-то его оптимизировать, чтобы повысить производительность?
@jangorecki
@ franknarf1 , это классный синтаксис C, хотя не уверен, что здесь это не сильно усложнит.
var > 1 ? d : e
тоже может работать, не так ли?
Да, это было бы круто. Приоритет оператора может мешать без {}
, как указал @renkun-ken ( ex = quote(x & y ? a+b : v+w); str(rapply(as.list(ex), as.list, how="replace"))
)
Я немного смущен здесь.
Делает
dt[, .SD, by = id, having = mean(var) > 1]
иметь какое-либо преимущество перед
dt[, if(mean(var) > 1) .SD, by = id]
поскольку
mean(var) > 1
всегда будет оцениваться для каждой группы. Служит ли он только синтаксическим сахаром, или мы пытаемся как-то его оптимизировать, чтобы повысить производительность?
Я думаю, до сих пор я предпочитал having=
, потому что я нахожу его немного более понятным для чтения и представляю, что его легче поддерживать по сравнению с добавлением дополнительной синтаксической магии в j
. С другой стороны, я думаю, что мог бы вместо этого предпочесть синтаксическую магию j
, поскольку
if () ...
; и как способ ?
также, если это осуществимо.j
, то не нужно отвечать на дополнительные вопросы о его поведении (например, DT[, x := if (cond) y, by=id]
создает NA, если условие выполняется в одних группах, но не в других, и такое поведение не должно t нужно заново объяснять для having=
).Что касается оптимизации, похоже, есть много примеров, когда само условие наличия могло бы выиграть от какой-либо версии GForce, поскольку обычно это выражение вроде max(x) > 0
, max(x) == 0
.
Для моего собственного использования, помимо оптимизации, я думаю, это было бы в основном полезно для случая групп только для возврата, упомянутого выше https://github.com/Rdatatable/data.table/issues/1269 .
> dt[, if (mean(var) > 1) .(), by=id]
> # instead of ...
> dt[, mean(var) > 1, by=id][V1 == TRUE, !"V1"]
id
1: 2
Хорошие моменты Фрэнк. в дополнение к огромному сборнику вариантов использования, которые вы
построен (еще раз спасибо!).
на самом деле может быть проще использовать GForce в версии have=, так как мы можем
просто примените логику gforce к тому, чтобы иметь аналог j, а не пытаться сделать
NSE, чтобы сделать то же самое.
хотя это может взаимодействовать с WIP Яна по перемещению большого количества j-кода на C - любой
мысли есть Ян?
В субботу, 15 февраля 2020 г., 13:40. Фрэнк уведомления@github.com написал:
@jangorecki https://github.com/jangorecki
@franknarf1 https://github.com/franknarf1 это классный синтаксис C,
хотя не уверен, что это не сильно усложнит здесь.
переменная > 1? d : e тоже может работать, не так ли?Да, это было бы круто. Приоритет оператора может мешать без
{}, как указал @renkun-ken https://github.com/renkun-ken (ex =
цитата (x & y ? a+b : v+w); str(rapply(as.list(ex), as.list, как="заменить"))
)Я немного смущен здесь.
Делает
dt[, .SD, by = id, имея = mean(var) > 1]
иметь какое-либо преимущество перед
dt[, if(mean(var) > 1) .SD, by = id]
поскольку среднее (var) > 1 всегда будет оцениваться для каждой группы. Это только
служить синтаксическим сахаром, или мы пытаемся как-то оптимизировать это
иметь более высокую производительность?Я думаю, до сих пор я предпочитал иметь =, потому что я нахожу это немного
яснее читать и представлять, что его легче поддерживать по сравнению с добавлением
дальнейшая синтаксическая магия к j. С другой стороны, я думаю, что мог бы
вместо этого предпочитайте магию синтаксиса j, так как
- Я привык, если () ... уже; и нравится? тоже, если это
достижимый.- Если он интегрирован в j, то никаких дополнительных вопросов задавать не нужно.
ответили о его поведении (например, DT[, x := if (cond) y, by=id] создает
NAs, если условие выполняется в одних группах, но не в других, и такое поведение
не нужно повторно объяснять наличие =).Что касается оптимизации, похоже, есть много примеров, когда
само условие наличия может выиграть от какой-либо версии GForce,
поскольку обычно это выражение типа max(x) > 0, max(x) == 0.Для моего собственного использования, помимо оптимизации, я думаю, это было бы в основном
полезно для случая групп только для возврата, упомянутого выше # 1269
https://github.com/Rdatatable/data.table/issues/1269dt[, если (среднее(var) > 1).(), by=id]
вместо ...
dt[, mean(var) > 1, by=id][V1 == TRUE, !"V1"]
я бы
1:2—
Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/Rdatatable/data.table/issues/788?email_source=notifications&email_token=AB2BA5OCN4IW3N6QQJU6RJ3RC555BA5CNFSM4ATSQPMKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEL3CK7A#issuecomment
или отписаться
https://github.com/notifications/unsubscribe-auth/AB2BA5MD7ZXWSRRHVEJM6C3RC555BANCNFSM4ATSQPMA
.
j-код, который нужно переместить в C, — это код, который отвечает только за выбор столбца, поэтому угадывание аргумента with
. Не буду здесь мешать.
Поскольку FR предназначен для добавления параметра "имеющий"... , слово having
должно быть где-то в решении. Оптимизация для тернарных операторов кажется отдельной проблемой.
Я предпочитаю having.i()
из-за мантры data.table: подмножество/порядок в i, выбор в j, группировка по. having
— это всего лишь частный случай подмножества.
В любом случае, если есть новый аргумент having
, будет ли API поддерживать аргумент $# i
? Большинство вариантов использования, похоже, не нуждаются в этом требовании.
Каким должно быть поведение при заказе? То есть большинство текущих подходов автоматически меняют порядок:
library(data.table)
dt = data.table(grp = c(1L, 2L, 1L, 2L), x = letters[sample(4L)])
dt
#> grp x
#> <int> <char>
#> 1: 1 a
#> 2: 2 b
#> 3: 1 c
#> 4: 2 d
dt[dt[, .I[.N > 0L], by = grp]$V1]
#> grp x
#> <int> <char>
#> 1: 1 a
#> 2: 1 c
#> 3: 2 b
#> 4: 2 d
Должен ли аргумент having
возвращать результат, переупорядоченный в соответствии с by
?
Каким должно быть поведение при заказе?
Должен ли аргументhaving
возвращать результат, переупорядоченный в соответствии сby
?
@ColeMiller1 Между прочим, я ожидаю, что having=
появится только тогда, когда также появится by=
, поэтому результаты будут сгруппированы, как в вашем примере с ...$V1
.
Да, я ожидаю, что порядок будет последовательным:
DT[i, j, by, having]
# < == >
DT[i, if (having) j, by]
Я думаю, что не было соглашения об API, особенно о новом аргументе having
в [
. @mattdowle wdyt?
Текущий подход к использованию DT[, if (.N > 1L) .SD, col1]
хорош, не очень сложен, легко расширяется, но его немного сложнее оптимизировать.
Моя идея состояла в том, чтобы использовать having
как вызов функции в i
: DT[having(N > 1L), .N, col1]
, но тогда невозможно обеспечить нормальное подмножество для i
.
В качестве альтернативы новый аргумент может быть подаргументом by
, не особо задумывался об этом, но что-то вроде DT[, .N, by=.(col1, .having = N > 1L)]
, поэтому дополнительный аргумент, связанный с группировкой, инкапсулирован в by
аргумент. Это правильный способ увеличить количество аргументов.
Самый полезный комментарий
Другой пример из SO . Его можно использовать для выбора строго уникальных строк (относится к #1163):
Обратите внимание, что
Bigdt[, if (.N == 1L) .SD, by=names(Bigdt)]
здесь не работает, так как.SD
пусто. Возможно, этому может помочь #1269.И еще один из SO: http://stackoverflow.com/q/38272608/ Они хотят выбирать группы на основе материала в последней строке, поэтому
having =
состояние здоровья[.N] == "not healthy"
должно это делать.И еще один простой случай (фильтрация по размеру): http://stackoverflow.com/q/39085450/
И еще один , с антиприсоединением:
Впрочем, не такой уж и отличный пример.
И еще один с ответом вроде
dt[, if(uniqueN(time)==1L) .SD, by=name, .SDcols="time"]
И еще: http://stackoverflow.com/q/43354165/
И еще: http://stackoverflow.com/q/43613087/
Другой (хотя он может быть удален): http://stackoverflow.com/q/43635968/
Другой http://stackoverflow.com/a/43765352/
Другой http://chat.stackoverflow.com/transcript/message/37148860#37148860
Другой https://stackoverflow.com/questions/45464333/assign-a-binary-vector-based-on-blocks-of-data-within-another-vector/
Другой
Другой https://stackoverflow.com/q/45557011/
Haiyou https://stackoverflow.com/questions/45598397/filter-data-frame-matching-all-values-of-a-vector
Гм май https://stackoverflow.com/a/45721286/
лингвай иге https://stackoverflow.com/a/45820567/
и https://stackoverflow.com/q/46251221/
уно мас https://stackoverflow.com/questions/46307315/show-sequences-that-include-a-variable-in-r
тамбем https://stackoverflow.com/q/46638058/
И другой. Я хочу подмножить мою таблицу данных (myDT) для записей, которых нет в справочной таблице (idDT):
Однако это было бы неэффективно, поскольку моя желаемая нотация влечет за собой каждое значение by=, создающее отдельное соединение с idDT. В этом смысле, возможно, это не лучший пример.
mais um https://stackoverflow.com/questions/47765283/r-data-table-group-by-where/47765308?noredirect=1#comment82524998_47765308 может сделать
DT[, if (any(status == "A") && !any(status == "B")) .SD, by=id]
или с параметромDT[, .SD, by=id, having = any(status == "A") && !any(status == "B")]
а затем https://stackoverflow.com/a/48669032/
m[, if(isTRUE(any(passed))) .SD, by=id]
должно бытьm[by = id, having = isTRUE(any(passed))]
лучший пример https://stackoverflow.com/q/49072250/
Эйн Андерер https://stackoverflow.com/a/49211292/
stock_profile[, sum(Value), by=Pcode, having=any(Location=="A" & NoSales == "Y")][, sum(V1)]
больше мм https://stackoverflow.com/a/49366998/
другой https://stackoverflow.com/a/49919015/
y https://stackoverflow.com/questions/50257643/deleting-rows-in-r-with-value-less-than-x
Моар https://stackoverflow.com/q/54582048
е https://stackoverflow.com/q/56283005
сохранить группы, если .N ==k (также много в цели обмана)
сохранить группы, если они есть (diff (sorted_col)) <= порог https://stackoverflow.com/q/57512417
сохранить, если max (x) < порог https://stackoverflow.com/a/57698641