Zauważyłem pewne dziwne zachowanie danych.table, mam nadzieję, że ktoś, kto rozumie dane.tabel lepiej niż mogę wyjaśnić.data.table "list" versus ": =" w radzeniu sobie z NaN
Say mam ten data.table:
library(data.table)
DT <- data.table(
C1 = c(rep("A", 4), rep("B",4), rep("C", 4)),
C2 = c(rep("a", 3), rep("b",3), rep("c",3), rep("d",3)),
Val = c(1:5, NaN, NaN, 8,9,10,NaN,12))
DT
C1 C2 Val
1: A a 1
2: A a 2
3: A a 3
4: A b 4
5: B b 5
6: B b NaN
7: B c NaN
8: B c 8
9: C c 9
10: C d 10
11: C d NaN
12: C d 12
Teraz, w moim umyśle, następujące dwie metody powinien wygenerować takie same wyniki, ale tak nie jest.
TEST1 <- DT[, agg := min(Val, na.rm = TRUE), by = c('C1', 'C2')]
TEST1 <- data.table(unique(TEST1[, c('C1','C2','agg'), with = FALSE]))
TEST2 <- DT[, list(agg = min(Val, na.rm = TRUE)), by = c('C1', 'C2')]
TEST1
C1 C2 agg
1: A a 1
2: A b 4
3: B b 5
4: B c 8
5: C c 9
6: C d 10
TEST2
C1 C2 agg
1: A a 1
2: A b 4
3: B b 5
4: B c NaN
5: C c 9
6: C d 10
Jak widać, przy użyciu ": =" wytwarza minimalną wartość (C1, C2 = b = c) 8. Zważywszy na wyniki poleceń listę w NaN. Co zabawne, dla (C1 = B, C2 = b) i (C1 = C, C2 = d), które również mają NaN, polecenie list generuje wartość. Uważam, że tak jest, ponieważ w przypadku, gdy NaN jest pierwszy przed wartością dla danej kombinacji C1 C2, wynik NaN. Podczas gdy w dwóch pozostałych przypadkach NaN występuje po wartości.
Dlaczego tak się dzieje?
Zauważam, że jeśli NAN zostaną zastąpione NA, wtedy wartości są generowane bez problemów.
nie pomysł, ale 'DT [lista (dwumecz = min (.SD $ Val, na.rm = TRUE)), by = c ('C1', 'C2')]' działa również – rawr
Or 'DT [, list (agg = min (c (Val), na.rm = TRUE)), by =. (C1, C2)]' To jest trochę dziwne, ale równoważny krok w 'dplyr' działa po konwersji do 'data.frame'. – akrun
Zdecydowanie powinieneś zgłosić błąd. Podejrzewam, że jest to spowodowane "wewnętrzną" implementacją funkcji 'data.table'' min'. Wewnątrz operacji 'data.table' niektóre funkcje (jak' min', 'max' i' sum') są zastępowane przez szybsze wersje 'data.table'. Jeśli wywołasz jawnie funkcję 'base', otrzymasz poprawne wyjście:' DT [, list (agg = base :: min (Val, na.rm = TRUE)), by = c ('C1', 'C2')] '. Nie mam pojęcia, dlaczego 'data.table' wydaje się powracać do' base :: min' kiedy jest używane w połączeniu z ': ='. – nicola