Actualmente, para tener el equivalente (o algo similar) de la cláusula having
SQL, debe escribir [.data.table
primero usando by
y luego introducir el resultado en i
parámetro de un segundo [.data.table
, como en:
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
Otra opción es usar una declaración condicional dentro j
, muy potente, lo hago todo el tiempo, y hasta ahora no hay nada que la sintaxis actual no me permita hacer. Sin embargo, tener un parámetro having
creo que permitirá escribir códigos mucho más claros y legibles. Por ejemplo lo anterior se puede escribir como:
dt[, if(mean(var) > 1) .SD, by = id]
Lo que propongo es algo como:
dt[, .SD, by = id, having = mean(var) > 1]
La idea es tener una expresión que siempre se evalúe como una lógica de longitud 1 que diga si j
debe evaluarse o no para el grupo actual.
Gracias,
michele
Gran FR. También he estado reflexionando sobre este caso de uso durante bastante tiempo. Podemos hacer esto sin el argumento adicional como este:
dt[, .SD[mean(var)>1], by=id]
(Pero para la velocidad, necesitará una optimización de .SD[.]
internamente - #735).
Es muy probable que en este caso recurramos a .I
en su lugar:
dt[dt[, .I[mean(var) > 1], by=id]$V1]
Y sería genial obtener esto directamente (incluso mejor si podemos lograrlo sin having
) - ¿quizás si la expresión j
se evalúa como un vector lógico de 1 columna? Solo pensando en voz alta.
Hola Arun. Gracias por la respuesta. Una vez que la optimización de .SD
esté disponible, esto sería solo una cuestión de "gusto" en términos de lo que es más claro para leer entre:
dt[, .SD[mean(var)>1], by=id]
y
dt[, .SD, by = id, having = mean(var) > 1]
Aunque el segundo también puede tener un mayor atractivo para las personas que vienen de otros idiomas (SQL en particular). Pero, de nuevo, esto podría ser sólo mi opinión. Tal vez solo usé SQL demasiado en el último período (lol).
En lo que respecta a la parte del sabor, realmente no me gusta agregar un parámetro adicional, cuando se puede lograr con una sintaxis simple y estándar (es decir, la primera opción anterior).
Curioso. Estaba seguro de que tú eras el que más apreciaría esto :-) (considerando lo mucho que querías eliminar by-without-by, principalmente para mejorar la legibilidad, especialmente para las personas que vienen de otros idiomas, si no recuerdo mal). De todos modos, sé que los dos son escenarios bastante diferentes. Solo quería compartir mi punto de vista,:
[.data.table
realmente no dañanj
para un grupo en particularLas razones por las que no me gustó el silencio por-sin-por y "tener" son en realidad las mismas: no me gusta recordar cosas adicionales, ya sean parámetros adicionales o comportamientos extra extraños.
Yo diría que la primera expresión que escribió es mucho más fácil de leer, porque no tiene que seguir leyendo la línea, luego descubrir que se especifica algún parámetro nuevo y tener que volver al principio de la oración y reevaluar su modelo mental de lo que está pasando.
¿Qué piensas de no agregar having
arg a [
, sino convertirlo en la función having()
y hacer que funcione en el argumento i
, lo mismo que order()
funciona, por ejemplo:
dt[ having(var > 1), .(var = mean(var)), by = id ]
# would perform below without additional copy:
dt[, .(var = mean(var)), by = id ][ var > 1 ]
having
sería una función para evaluar su argumento en el marco de dt
y proporcionar filtrado a i
.
Creo que este FR está estrechamente relacionado con https://github.com/Rdatatable/data.table/issues/1269 "Returning only groups". A menudo quiero obtener grupos con algún atributo y almacenarlos en un vector, como my_teams
en esta publicación SO . Aquí está la línea relevante:
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
Con los FR having
y "Solo grupos que regresan", esto podría ser algo como
my_teams <- FantasyTeams[, .(), by = team_no, having = { max(table(Team)) <= 3 }]$team_no
El código es igual de largo, pero lo prefiero, así que no tengo que leer j
detenidamente para entender el objetivo.
Otro ejemplo de SO . El objetivo es sobrescribir la columna Value
con 3L
si se cumple alguna condición a nivel de grupo:
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 ) }]
Además de una sintaxis posiblemente más agradable, supongo que la forma having=
también podría ser más eficiente, ya que solo es necesario modificar un subconjunto de subgrupos. La forma más eficiente sin having=
probablemente parezca...
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)]
que son bastante enrevesados.
Editar : Y otro ejemplo para actualizar si/cuando esta función esté disponible: http://stackoverflow.com/q/36292702
(2016/4/26:) http://stackoverflow.com/q/36869784
(2016/06/16:) http://stackoverflow.com/q/37855013/
Otro ejemplo de SO . Podría usarse para seleccionar filas estrictamente únicas (relacionadas con #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}]
Tenga en cuenta que Bigdt[, if (.N == 1L) .SD, by=names(Bigdt)]
no funciona aquí, ya que .SD
está vacío. Sin embargo, tal vez eso podría ser ayudado por # 1269 .
Y otro de SO: http://stackoverflow.com/q/38272608/ Quieren seleccionar grupos en función de las cosas en la última fila, por lo que having =
condición de salud [.N] == "not healthy"
debería hacerlo.
Y otro caso sencillo (filtrando por tamaño): http://stackoverflow.com/q/39085450/
Y otro , con un anti join:
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) ]
Sin embargo, no es un gran ejemplo.
Y otro con una respuesta como dt[, if(uniqueN(time)==1L) .SD, by=name, .SDcols="time"]
Y otro: http://stackoverflow.com/q/43354165/
Y otro: http://stackoverflow.com/q/43613087/
Otro (aunque podría eliminarse): http://stackoverflow.com/q/43635968/
Otro http://stackoverflow.com/a/43765352/
Otro http://chat.stackoverflow.com/transcript/message/37148860#37148860
Un autre https://stackoverflow.com/q/45557011/
Haiyou https://stackoverflow.com/questions/45598397/filter-data-frame-matching-all-values-of-a-vector
Um más https://stackoverflow.com/a/45721286/
lingwai yige https://stackoverflow.com/a/45820567/
y https://stackoverflow.com/q/46251221/
uno mas https://stackoverflow.com/questions/46307315/show-sequences-that-include-a-variable-in-r
también https://stackoverflow.com/q/46638058/
Y otro. Quiero dividir mi tabla de datos (myDT) en entradas que no se encuentran en una tabla de referencia (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]
Sin embargo, esto sería ineficiente, ya que mi notación deseada implica que cada valor por = haga una unión separada a idDT. En ese sentido, quizás no sea el mejor ejemplo.
mais um https://stackoverflow.com/questions/47765283/r-data-table-group-by-where/47765308?noredirect=1#comment82524998_47765308 podría hacer DT[, if (any(status == "A") && !any(status == "B")) .SD, by=id]
o con un parámetro que tiene DT[, .SD, by=id, having = any(status == "A") && !any(status == "B")]
y luego https://stackoverflow.com/a/48669032/ m[, if(isTRUE(any(passed))) .SD, by=id]
debería ser m[by = id, having = isTRUE(any(passed))]
más un ejemplo https://stackoverflow.com/q/49072250/
ein anderer https://stackoverflow.com/a/49211292/ stock_profile[, sum(Value), by=Pcode, having=any(Location=="A" & NoSales == "Y")][, sum(V1)]
más um https://stackoverflow.com/a/49366998/
autre https://stackoverflow.com/a/49919015/
y https://stackoverflow.com/questions/50257643/deleting-rows-in-r-with-value-less-than-x
moar https://stackoverflow.com/q/54582048
y https://stackoverflow.com/q/56283005
mantenga los grupos si .N==k (también muchos en el objetivo duplicado )
mantener grupos si los hay (diff (sorted_col)) <= umbral https://stackoverflow.com/q/57512417
mantener si max(x) <umbral https://stackoverflow.com/a/57698641
@eantonya En mi humilde opinión, agregar el parámetro having
hará que sea más fácil de recordar. La concisión excesiva puede ser difícil de memorizar. Además, hacer data.table
más como SQL no es una mala idea.
En data.table
Preguntas frecuentes:
2.16 He oído que la sintaxis de data.table es análoga a SQL.
Sí : ...
@ywhuofu data.table ya acepta la función order
para el argumento i
, que es lo que esperaría el usuario base de R. De la misma manera que traducimos _ORDER_ de sql a i = order(...)
podemos hacerlo con _HAVING_. Encaja bien, ya que i
en data.frame se usa para crear subconjuntos (_tener_ es solo un subconjunto retrasado después de la agregación) o reordenación.
¿Podría ser esta la 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
He implementado esta versión aunque establece una restricción de usar solo funciones optimizadas gforce
así como algunas funciones que no dependen de agrupaciones (por ejemplo, +
, |
, &
, etc.). En SQL, las funciones de resumen son las que se usan, aunque lo entendería si Cdogroups
quisiera ser compatible.
Una nota adicional. Parece que sería difícil encajar dt[having(var > 3), .(var = mean(x)), by = .(grp)]
dentro del código actual '[.data.table'
. Tendría que haber algunas comprobaciones para asegurarse de que la sintaxis sea correcta.
```
n = 1e6
grps = 1e5
cabeza_n = 2L
dt = data.table::data.table(x = muestra(grps, n, TRUE), y = runif(n))
expresión min mediana
1 lw[tener.i(.N < 2L | sum(y) > 11 | mediana(y) < 0.7, by = x)] 114.13ms 124.98ms
2 dt[dt[, .I[.N < 2L | suma(y) > 11 | mediana(y) < 0.7], por = x]$V1] 4000ms 4000ms
expresión min mediana itr/sec
mem_alloc gc/sec
n_itr
1 lw[tener.i(.N < 2L, por = x)] 30.2ms 35.3ms 27.9 8.02MB 3.99 14
2 dt[dt[, .I[.N < 2L], por = x]$V1] 106,1 ms 110,4 ms 8,81 6,13 MB 10,6 5
Preferiría esto como un parámetro agregado, denominado como having=
o group_filter=
(o algo más que no dependa de la conciencia de SQL para saber lo que hace a la vista).
por ejemplo, creo que sería confuso combinar filtros de fila en i
con filtros de nivel de grupo también en i
¿Funcionaría having =
en un subconjunto de los datos o solo podría usar el i
o el argumento having
? También asumo que having
ocurriría antes de que se evalúe j
. ¿Cómo funcionarían .BY
y .GRP
y pronto .NGRP
con ```have = ````?
No hay muchas opciones sintácticas:
having
i
, j
, by
.Si se necesitan tanto el filtro de fila como el filtro de grupo, dt[row_selector & group_selector, ...]
no se ve bien, por lo tanto, parece que para tal caso de uso, el filtro de fila y el filtro de grupo no deberían aparecer en el mismo argumento. Entonces se descarta i
.
Entonces no habrá muchas opciones sintácticas.
Aprovechar by
podría hacer que parezca confuso. Por ejemplo,
dt[, .SD, by = having(.(id), mean(var > 1))]
dt[, .SD, by = id ~ mean(var) > 1]
Agregar una función especial a j
no se ve bien.
dt[, having(mean(var) > 1, .SD), by = id]
Ahora, el código que me parece mejor es la versión más original
dt[, if (mean(var) > 1) .SD, by = id]
dt[, if (mean(var) > 1) .(x = sum(x), y = sum(y)), by = id]
Lo que realmente quiero es mantener la optimización realizada después del filtrado grupal. ¿Podemos detectar la expresión if
en j
y optimizarla, como hacer que GForce funcione dentro de la instrucción if?
@ renkun-ken ¿O sobrecargar otro operador infijo?
dt[, mean(var) > 1 ? .SD, by=id]
Una ventaja de un símbolo especial sobre if
es que no hay posibilidad de que el usuario coloque un else
correspondiente más adelante.
@franknarf1 Parece que mientras intentamos detectar if
en j
, también podríamos comprobar que if
tiene else if
y else
. Podríamos optimizar if
-solo caso y dejar if-else
sin optimizar. Tal vez más tarde podamos manejar el caso if-else
también. Personalmente, sigo prefiriendo optimizar el código a anular o aprovechar demasiado los operadores existentes.
@ franknarf1 esta es una sintaxis de C genial, aunque no estoy seguro de si no se complicaría demasiado aquí.
var > 1 ? d : e
también podría funcionar, ¿no?
var > 1 ? d : e
parece conciso, pero solo funciona para el caso simple en línea, ya que d
y e
podrían ser algo así como {...}
y la precedencia del operador puede ser confusa. ¿Solo estamos tratando de permitir que .SD
realice un filtrado de grupo puro, o cualquier expresión en j
aquí?
Agregar sintaxis tiene el problema de que el usuario debe tener en cuenta que la sintaxis se maneja especialmente y no debería funcionar dentro j
. Por ejemplo, el usuario puede esperar
dt[, mean(var) > 1 ? 0 : (sd(var) < 1 ? 1 : 0), by = id]
para trabajar, e incluso
dt[, mean(var) > 1 ? 0 : 1]
dt[, mean(var) > 1 ? 0 : (sd(var) < 1 ? 1 : 0)]
para trabajar en general.
Estoy un poco confundido aquí.
Lo hace
dt[, .SD, by = id, having = mean(var) > 1]
tener alguna ventaja sobre
dt[, if(mean(var) > 1) .SD, by = id]
ya que mean(var) > 1
siempre se evaluará para cada grupo. ¿Solo sirve como un azúcar sintáctico o estamos tratando de optimizar esto de alguna manera para tener un mayor rendimiento?
@jangorecki
@ franknarf1 esta es una sintaxis de C genial, aunque no estoy seguro de si no se complicaría demasiado aquí.
var > 1 ? d : e
también podría funcionar, ¿no?
Sí, eso estaría genial. La precedencia del operador podría interponerse sin {}
s como señaló @renkun-ken ( ex = quote(x & y ? a+b : v+w); str(rapply(as.list(ex), as.list, how="replace"))
)
Estoy un poco confundido aquí.
Lo hace
dt[, .SD, by = id, having = mean(var) > 1]
tener alguna ventaja sobre
dt[, if(mean(var) > 1) .SD, by = id]
ya que siempre se evaluará
mean(var) > 1
para cada grupo. ¿Solo sirve como un azúcar sintáctico o estamos tratando de optimizar esto de alguna manera para tener un mayor rendimiento?
Supongo que hasta ahora había preferido having=
porque lo encuentro un poco más claro de leer e imagino que es más fácil de mantener en comparación con agregar más magia sintáctica a j
. Por otro lado, creo que preferiría la sintaxis mágica j
, ya que
if () ...
; y me gusta la forma ?
también si es factible.j
, entonces no es necesario responder preguntas adicionales sobre su comportamiento (por ejemplo, DT[, x := if (cond) y, by=id]
crea NA si la condición se cumple en algunos grupos pero no en otros y este comportamiento no debería t necesita ser explicado nuevamente por having=
).Con respecto a la optimización, parece que hay muchos ejemplos en los que la condición de tener en sí misma podría beneficiarse de alguna versión de GForce, ya que generalmente es una expresión como max(x) > 0
, max(x) == 0
.
Para mi propio uso, además de la optimización, supongo que sería más útil para el caso de grupos de devolución solo mencionado anteriormente 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
Buenos puntos Frank. además del enorme compendio de casos de uso que has
construido (¡gracias de nuevo por cierto!).
de hecho, puede ser más fácil hacer GForce en la versión being= ya que podemos
simplemente aplique la lógica gforce para tener similar a j en lugar de intentar hacer
NSE para lograr lo mismo.
aunque eso puede interactuar con el WIP de Jan para mover una gran cantidad de código j a C, cualquier
pensamientos hay Jan?
El sábado 15 de febrero de 2020 a la 1:40 p. m., Frank [email protected] escribió:
@jangorecki https://github.com/jangorecki
@franknarf1 https://github.com/franknarf1 esta es una sintaxis C genial,
aunque no estoy seguro si no se complicaría mucho aquí.
var > 1 ? d : Podría funcionar también, ¿no?Sí, eso estaría genial. La precedencia del operador puede interferir sin
{}s como señaló @renkun-ken https://github.com/renkun-ken (ex =
cita(x & y ? a+b : v+w); str(rapply(como.lista(ex), como.lista, como="reemplazar"))
)Estoy un poco confundido aquí.
Lo hace
dt[, .SD, por = id, teniendo = media(var) > 1]
tener alguna ventaja sobre
dt[, si(media(var) > 1) .SD, por = id]
ya que mean(var) > 1 siempre se evaluará para cada grupo. ¿Es solo
servir como un azúcar sintáctico o estamos tratando de optimizar esto de alguna manera
para tener un mayor rendimiento?Supongo que hasta ahora hubiera preferido tener= porque lo encuentro un poco
más claro de leer e imaginar que es más fácil de mantener en comparación con agregar
más magia sintáctica a j. Por otro lado, creo que podría
en su lugar prefiero la magia de la sintaxis j, ya que
- Estoy acostumbrado a si () ... ya; y como el? demasiado si es
factible.- Si está integrado en j, entonces no es necesario hacer preguntas adicionales.
respondió sobre su comportamiento (por ejemplo, DT[, x := if (cond) y, by=id] crea
NA si la condición se cumple en algunos grupos pero no en otros y este comportamiento
no debería ser necesario volver a explicar por tener =).Con respecto a la optimización, parece que hay muchos ejemplos en los que
la condición de tener en sí podría beneficiarse de alguna versión de GForce,
ya que normalmente es una expresión como max(x) > 0, max(x) == 0.Para mi propio uso, además de la optimización, supongo que sería principalmente
útil para el caso de grupos de retorno solo mencionado anteriormente # 1269
https://github.com/Rdatatable/data.table/issues/1269dt[, si (media(var) > 1) .(), por=id]
en lugar de ...
dt[, media(var) > 1, por=id][V1 == VERDADERO, !"V1"]
identificación
1: 2—
Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/788?email_source=notifications&email_token=AB2BA5OCN4IW3N6QQJU6RJ3RC555BA5CNFSM4ATSQPMKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEL3CK7A#issue665comment-598
o darse de baja
https://github.com/notifications/unsubscribe-auth/AB2BA5MD7ZXWSRRHVEJM6C3RC555BANCNFSM4ATSQPMA
.
El código j que se moverá a C es el código responsable solo de la selección de columnas, por lo que debe adivinar el argumento with
. No interferirá aquí.
Dado que FR es para agregar un parámetro 'tener'... , la palabra having
debería estar en algún lugar de la solución. La optimización para operadores ternarios parece un tema aparte.
Mi preferencia por having.i()
se debe al mantra de data.table: subconjunto/ordenar en i, seleccionar en j, agrupar en por. having
es solo un caso especial de creación de subconjuntos.
Independientemente, si hay un nuevo argumento having
, ¿la API admitiría un argumento $# i
? La mayoría de los casos de uso no parecen necesitar ese requisito.
¿Cuál debe ser el comportamiento de ordenar? Es decir, la mayoría de los enfoques actuales reordenan automáticamente:
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
¿Debe having
arg devolver un resultado que se reordena de acuerdo con by
?
¿Cuál debe ser el comportamiento de ordenar?
¿Debehaving
arg devolver un resultado que se reordena de acuerdo conby
?
@ColeMiller1 Fwiw, esperaría que having=
solo apareciera cuando también aparece by=
, por lo que los resultados se agruparían como en su ejemplo con ...$V1
.
Sí, esperaría que el orden fuera consistente:
DT[i, j, by, having]
# < == >
DT[i, if (having) j, by]
Creo que no hubo acuerdo sobre la API, particularmente sobre tener un nuevo argumento having
en [
. @mattdowle ¿qué pasa?
El enfoque actual de usar DT[, if (.N > 1L) .SD, col1]
es bueno, no es realmente complicado, fácil de extender, pero un poco más difícil de optimizar.
Mi idea era usar having
como llamada de función en i
: DT[having(N > 1L), .N, col1]
, pero entonces no es posible proporcionar un subconjunto normal a i
.
Alternativamente, el nuevo argumento podría ser un subargumento de by
, no lo he pensado mucho, pero algo así como DT[, .N, by=.(col1, .having = N > 1L)]
, por lo que el argumento adicional relacionado con la agrupación se encapsula en by
argumento. Esta es la forma correcta de escalar el número de argumentos.
Comentario más útil
Otro ejemplo de SO . Podría usarse para seleccionar filas estrictamente únicas (relacionadas con #1163):
Tenga en cuenta que
Bigdt[, if (.N == 1L) .SD, by=names(Bigdt)]
no funciona aquí, ya que.SD
está vacío. Sin embargo, tal vez eso podría ser ayudado por # 1269 .Y otro de SO: http://stackoverflow.com/q/38272608/ Quieren seleccionar grupos en función de las cosas en la última fila, por lo que
having =
condición de salud[.N] == "not healthy"
debería hacerlo.Y otro caso sencillo (filtrando por tamaño): http://stackoverflow.com/q/39085450/
Y otro , con un anti join:
Sin embargo, no es un gran ejemplo.
Y otro con una respuesta como
dt[, if(uniqueN(time)==1L) .SD, by=name, .SDcols="time"]
Y otro: http://stackoverflow.com/q/43354165/
Y otro: http://stackoverflow.com/q/43613087/
Otro (aunque podría eliminarse): http://stackoverflow.com/q/43635968/
Otro http://stackoverflow.com/a/43765352/
Otro http://chat.stackoverflow.com/transcript/message/37148860#37148860
Otro https://stackoverflow.com/questions/45464333/assign-a-binary-vector-based-on-blocks-of-data-within-another-vector/
Otro https://stackoverflow.com/questions/32259620/how-to-remove-unique-entry-and-keep-duplicates-in-r/32259758#32259758
Un autre https://stackoverflow.com/q/45557011/
Haiyou https://stackoverflow.com/questions/45598397/filter-data-frame-matching-all-values-of-a-vector
Um más https://stackoverflow.com/a/45721286/
lingwai yige https://stackoverflow.com/a/45820567/
y https://stackoverflow.com/q/46251221/
uno mas https://stackoverflow.com/questions/46307315/show-sequences-that-include-a-variable-in-r
también https://stackoverflow.com/q/46638058/
Y otro. Quiero dividir mi tabla de datos (myDT) en entradas que no se encuentran en una tabla de referencia (idDT):
Sin embargo, esto sería ineficiente, ya que mi notación deseada implica que cada valor por = haga una unión separada a idDT. En ese sentido, quizás no sea el mejor ejemplo.
mais um https://stackoverflow.com/questions/47765283/r-data-table-group-by-where/47765308?noredirect=1#comment82524998_47765308 podría hacer
DT[, if (any(status == "A") && !any(status == "B")) .SD, by=id]
o con un parámetro que tieneDT[, .SD, by=id, having = any(status == "A") && !any(status == "B")]
y luego https://stackoverflow.com/a/48669032/
m[, if(isTRUE(any(passed))) .SD, by=id]
debería serm[by = id, having = isTRUE(any(passed))]
más un ejemplo https://stackoverflow.com/q/49072250/
ein anderer https://stackoverflow.com/a/49211292/
stock_profile[, sum(Value), by=Pcode, having=any(Location=="A" & NoSales == "Y")][, sum(V1)]
más um https://stackoverflow.com/a/49366998/
autre https://stackoverflow.com/a/49919015/
y https://stackoverflow.com/questions/50257643/deleting-rows-in-r-with-value-less-than-x
moar https://stackoverflow.com/q/54582048
y https://stackoverflow.com/q/56283005
mantenga los grupos si .N==k (también muchos en el objetivo duplicado )
mantener grupos si los hay (diff (sorted_col)) <= umbral https://stackoverflow.com/q/57512417
mantener si max(x) <umbral https://stackoverflow.com/a/57698641