2013-05-20 8 views
34

Jeśli ma ramkę danychWłóż wiersz w data.table

set.seed(12345) 
df=data.frame(a=rnorm(5),b=rnorm(5)) 

można dodać wiersz przez np

df[6,] =c(5,6)

Gdybym teraz zrobić równowartość w data.table

library(data.table) 
dt=data.table(df) 
dt[6,]=c(5,6) 

nie powiedzie się z powodu błędu. Jaki jest właściwy sposób wstawiania wiersza do tabeli data.table?

+2

Myślę, że funkcja 'insert()' jest planowana dla tego pakietu, aby był relatywnie szybki, aby dodać wiersze, ale od tej chwili musisz wcześniej przydzielić 'nrow' tabeli danych. Może to: http://r-forge.r-project.org/tracker/index.php?func=detail&aid=1458&group_id=240&atid=978 – Frank

+8

Czy 'rbind (dt, list (5,6))' wystarcza dla ciebie cel, powód? – Roland

+2

btw ime za każdym razem, gdy myślałem, że muszę dodać wiersz po wierszu, myślałem w stylu C, a nie w stylu R - więc oprócz powyższych uwag powinieneś zastanowić się, czy naprawdę musisz to zrobić. – eddi

Odpowiedz

36

Aby rozwinąć na @Franks odpowiedź, czy w danym przypadku, gdy dodanie wiersza, to:

set.seed(12345) 
dt1 <- data.table(a=rnorm(5), b=rnorm(5)) 

Poniżej są równoważne; Uważam, że najpierw łatwiejsze do odczytania, ale sekundy szybciej:

microbenchmark(
    rbind(dt1, list(5, 6)), 
    rbindlist(list(dt1, list(5, 6)))   
) 

Jak widzimy:

       expr  min  lq median  uq  max 
      rbind(dt1, list(5, 6)) 160.516 166.058 175.089 185.1470 457.735 
rbindlist(list(dt1, list(5, 6))) 130.137 134.037 140.605 149.6365 184.326 

Jeśli chcesz wstawić wiersz gdzie indziej, co następuje będzie działać, ale nie całkiem:

rbindlist(list(dt1[1:3, ], list(5, 6), dt1[4:5, ])) 

lub nawet

rbindlist(list(dt1[1:3, ], as.list(c(5, 6)), dt1[4:5, ])) 

dawanie:

  a   b 
1: 0.5855288 -1.8179560 
2: 0.7094660 0.6300986 
3: -0.1093033 -0.2761841 
4: 5.0000000 6.0000000 
5: -0.4534972 -0.2841597 
6: 0.6058875 -0.9193220 

Jeśli modyfikując wiersz w miejscu (co jest preferowanym podejściem), trzeba będzie określić rozmiar data.table z góry tzn

dt1 <- data.table(a=rnorm(6), b=rnorm(6)) 
set(dt1, i=6L, j="a", value=5) # refer to column by name 
set(dt1, i=6L, j=2L, value=6) # refer to column by number 

Dzięki @ Boxuan, zmodyfikowałem tę odpowiedź, aby uwzględnić Twoją sugestię, która jest trochę szybsza i łatwiejsza do odczytania.

+1

dlaczego nie używać 'rbindlist (list (dt1, list (5,6))) jako drugiej opcji dla nieco lepszej czytelności? – Boxuan

+1

@Boxuan 'rbindlist (lista (dt1, lista (c (5, 6))))' daje mi 'Błąd ... Pozycja 2 ma 1 kolumnę, niezgodną z pozycją 1, która ma 2 kolumny ...' Zobacz wynik z 'list (c (5, 6))', który jest listą z jednym elementem vs. 'as.list (c (5, 6))', który ma dwa. – dardisco

+0

To dziwne. Mogę go uruchomić na mojej maszynie. Może mamy różne wersje? 'pakietVersion (" data.table ")' daje mi '[1] '1.9.4'' i' getRversion() 'daje mi' [1]' 3.2.0''. – Boxuan