2013-04-22 17 views
5

To jest z obserwacji podczas odpowiadania na to pytanie z @sds here.zrozumienie komunikatów optymalizacji przydziału przez odniesienie w data.table

Po pierwsze, niech mi przełącznik na wiadomości śladowych dla data.table:

options(datatable.verbose = TRUE) 
dt <- data.table(a = c(rep(3, 5), rep(4, 5)), b=1:10, c=11:20, d=21:30, key="a") 

Teraz załóżmy, że ktoś chce dostać sumę wszystkich kolumn zgrupowane według kolumny a, wtedy moglibyśmy zrobić:

dt.out <- dt[, lapply(.SD, sum), by = a] 

Załóżmy teraz, że chciałbym dodać również liczbę wpisów należących do każdej grupy do dt.out, a następnie zwykle przypisuję ją przez odwołanie w następujący sposób:

dt.out[, count := dt[, .N, by=a][, N]] 
# or alternatively 
dt.out[, count := dt[, .N, by=a][["N"]]] 

W tym zadaniu przez odniesienie, jeden z komunikatów data.table produkuje to:

RHS for item 1 has been duplicated. Either NAMED vector or recycled list RHS. 

To jest wiadomość z pliku w katalogu źródłowym data.table za assign.C. Nie chcę wklejać odpowiedniego fragmentu tutaj, ponieważ ma on około 18 linii. Jeśli to konieczne, po prostu zostaw komentarz, a wkleję kod. dt[, .N, by=a][["N"]] po prostu daje [1] 5 5. Tak więc jest to , a nie a named vector. A ja nie rozumiem, co to recycled list w RHS jest ..

Ale jeśli to zrobię:

dt.out[, `:=`(count = dt[, .N, by=a][, N])] 
# or equivalently 
dt.out[, `:=`(count = dt[, .N, by=a][["N"]])] 

Potem dostaję komunikat:

Direct plonk of unnamed RHS, no copy. 

Jak rozumiem tego, RHS został powielony w pierwszym przypadku, co oznacza, że ​​robi kopię (płytkie/głębokie, to nie wiem). Jeśli tak, dlaczego tak się dzieje?

Nawet jeśli nie, dlaczego zmiany przypisania przez odniesienie między dwoma wewnętrznie? Jakieś pomysły?

Aby wydobyć główny podstawowej pytanie, które miałem w głowie podczas pisania tego postu (i zdają się zapominać!): Czy to „mniej skuteczny” przypisać jako dt.out[, count := dt[, .N, by=a][["N"]]] (w porównaniu do drugiego sposobu prowadzenia to)?

+0

Z przyjemnością odpowiadam, ale jakie są pytania w S.O. sens? Na razie odpowiem na pierwszą część ... –

+0

Będę edytować pytanie, aby upewnić się, że moje pytanie, oprócz tych tutaj, jest * nieefektywne * do przypisania przy użyciu 'a: =. '. – Arun

+1

U góry jestem raczej pewien, że powinny to być 'options (datatable.verbose = TRUE)'. Nie ma opcji "datatable.warnings", ale nic nie narzekałoby, że ustawienie było nieskuteczne. –

Odpowiedz

6

Aktualizacja: Wyrażenie

DT[, c(..., lapply(.SD, .), ..., by=.] 

został zoptymalizowany wewnętrznie popełnić # 1242 z v1.9.3 (FR #2722). Oto zapis z NEWS:

o złożonych j-wyrażenia postaci DT[, c(..., lapply(.SD, fun)), by=grp] są teraz zoptymalizowane, tak długo jak .SD jest obecna tylko w formie lapply(.SD, fun).

Dla ex: DT[, c(.I, lapply(.SD, sum), mean(x), lapply(.SD, log)), by=grp]
jest zoptymalizowany do: DT[, list(.I, x=sum(x), y=sum(y), ..., mean(x), log(x), log(y), ...), by=grp]

Ale DT[, c(.SD, lapply(.SD, sum)), by=grp] na przykład nie jest jeszcze zoptymalizowana. To częściowo rozwiązuje FR #2722. Podziękowania dla Sama Steingolda za złożenie wniosku do FR.


gdzie mówi NAMED vector oznacza to, że w wewnętrznej znaczeniu R na poziomie C; tzn. czy obiektowi przypisano symbol i nazywa się go czymś, a nie tym, czy wektor atomowy ma atrybut "names", czy też nie. Wartość NAMED w strukturze SEXP przyjmuje wartość 0, 1 lub 2. R używa tego, aby wiedzieć, czy musi kopiować na subassign, czy nie. Zobacz rozdział 1.1.2 R-ints.

Co byłoby lepiej jest, jeśli optymalizacja j w data.table poradzi:

DT[, c(lapply(.SD,sum),.N), by=a] 

który działa, ale może być powolna. Obecnie tylko prostsza forma jest optymalizowana:

DT[, lapply(.SD,sum), by=a] 

Aby odpowiedzieć na główne pytanie, tak, co następuje:

Direct plonk of unnamed RHS, no copy. 

jest pożądane w stosunku do:

RHS for item 1 has been duplicated. Either NAMED vector or recycled list RHS. 

Innym sposobem osiągnięcia jest to:

dt.out[, count := dt[, .N, by=a]$N] 

Nie jestem całkiem pewien, dlaczego [["N"]] zwraca NAM(2) w porównaniu do $N, które nie.

+0

Dzięki Matthew za cierpliwość. Tak, już porównałem odpowiedź @ djhurio [** tutaj **] (http://stackoverflow.com/a/16134117/559784) (w tym samym poście, który podłączyłem na górze) i stwierdziłem, że jest wolniejsze. Przepraszam, jeszcze nie zapoznałem się z integracją R-C. Moje pytanie jest zasadniczo pomiędzy dwiema metodami przypisywania przez odniesienie: czy różne wiadomości w każdym przypadku mają cokolwiek wspólnego z efektywnością (mimo że rozumiem, że odpowiedź może mieć bardzo wiele wspólnego z czytaniem sekcji 1.1.2)? – Arun

+0

Dzięki Matthew. Rzeczywiście byłoby dobrze, gdyby 'DT <- DT [, c (lapply (.SD, sum), N), by = a]' zostały zoptymalizowane, ponieważ wtedy byłbym w stanie odrzucić stare 'DT' od razu. – sds

+0

@sds Ok. Czy możesz złożyć wniosek o funkcję? Dzięki. –

Powiązane problemy