Tengo el siguiente data.table (de hecho, mi data.table es mucho más grande (más grupos y más otras variables)):

Data <- data.table(Group = rep(c("a", "b"), each = 3),
                   Var = 1:6)

> print(Data)
   Group Var
1:     a   1
2:     a   2
3:     a   3
4:     b   4
5:     b   5
6:     b   6

Ahora quiero ordenar data.table según la variable Group pero solo si Group == "a". Mi pobre intento fue el siguiente:

> Data[Group == "a", .SD[.N:1]]
   Group Var
1:     a   3
2:     a   2
3:     a   1

Sé por qué esto está mal, pero no puedo pensar en una solución que conduzca a mi salida deseada:

   Group Var
1:     a   3
2:     a   2
3:     a   1
4:     b   4
5:     b   5
6:     b   6
0
TobiSonne 8 dic. 2019 a las 13:19

2 respuestas

La mejor respuesta

Tu intento funcionaría con

library(data.table)
Data[Group == "a"] <- Data[Group == "a", .SD[.N:1]]
Data
#    Group Var
#1:     a   3
#2:     a   2
#3:     a   1
#4:     b   4
#5:     b   5
#6:     b   6

Pero lo anterior solo invierte las filas si desea ordenar las filas en orden decreciente según Var que podría hacer

Data[Group == "a"] <- Data[Group == "a", .SD[order(-Var)]]

Si tienes varias columnas puedes hacer

cols <- c("a", "b")
Data[Group %in% cols] <- Data[Group %in% cols,.SD[order(-Var)],Group]

Un mejor enfoque con data.table es actualizar por referencia como lo sugiere @markus

Data[Group %in% cols, Var := .SD[order(-Var)]$Var]
3
Ronak Shah 8 dic. 2019 a las 12:53

Sin usar la notación .SD:

> Data[Group == "a", Var := sort(Var, decreasing = TRUE)]
> Data

   Group Var
1:     a   3
2:     a   2
3:     a   1
4:     b   4
5:     b   5
6:     b   6

Como tiene una gran tabla de datos y más grupos, es posible que desee considerar el uso de la notación .I (consulte artículo por @ nathaneastwood) ya que da como resultado un mejor rendimiento en algunas situaciones. Aquí, .I identificará los números de fila de interés. Cambiemos el ejemplo para que nos interesen dos grupos:

Data <- data.table(Group = rep(c("a", "b", "c"), each = 3), Var = 10:18)

Entonces:

> Data[Data[, .I[Group  %in% c("a", "c")]], Var := sort(Var, decreasing = TRUE), by = Group]

> Data
   Group Var
1:     a  12
2:     a  11
3:     a  10
4:     b  13
5:     b  14
6:     b  15
7:     c  18
8:     c  17
9:     c  16

Para completar, la idea básica está contenida en:

Data[Group %in% c("a", "c"), Var:= sort(Var, decreasing = TRUE), by = Group]
2
Vidhya G 8 dic. 2019 a las 12:08