2015-04-15 12 views
9

Mam obiekt data.table w R, który ma 9000 kolumn. Mój kod oblicza nowe wartości dla wszystkich 9 000 kolumn jednocześnie i zwraca wektor wartości. Chciałbym po prostu zamienić wiersz w tabeli data.table na wszystkie wartości naraz. W obiekcie dataFrame jest to łatwe. Jednak nie mogę dowiedzieć się, jak uzyskać to działa w data.table.Zaktualizuj cały wiersz w data.table w R

d <- data.table(q=c(1,2,3,4,5,6,7,8,9), x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 
d[q==1, := c(5,5,5,5)] # FAILS 
d[q==1, ] <- c(5,5,5,5) # FAILS 

Każdy pomysł, jak skutecznie zaktualizować cały wiersz na raz?

Odpowiedz

11

Można użyć names(d) dla LHS, a następnie użyć as.list aby przekształcić wektor do listy tak data.table zrozumie, że trzeba przypisać każdą wartość do kolumny inny zamiast wszystkich wartości do każda kolumna.

Ty także konwersję character wektora numeric się tutaj (kolumny x), więc data.table zwróci ostrzeżenie, w celu upewnienia się, że są świadomi tego.

vec <- c(5, 5, 5, 5) 
d[q == 1L, names(d) := as.list(vec)][] 
# q x y v 
# 1: 5 5 5 5 
# 2: 2 a 3 2 
# 3: 3 a 6 3 
# 4: 4 b 1 4 
# 5: 5 b 3 5 
# 6: 6 b 6 6 
# 7: 7 c 1 7 
# 8: 8 c 3 8 
# 9: 9 c 6 9 
0

ten może być również wykonane za pomocą set, w powyższym przykładzie (odniesienie liczby rzędów).

set(d, 1L, names(d), as.list(vec)) 

Ty może zdobyć prędkość używając set zamiast, ale stracić niektóre z korzyści, jeśli trzeba odzyskać numery wierszy w pierwszej kolejności.

# Create large data table 
DT = data.table(col1 = 1:1e5) 
cols = paste0('col', 1:9e3) 
for (col in cols){ DT[, col := 1:1e5, with = F] } 
vec <- rep(5,9e3) 

# Test options 
microbenchmark(
    row_idnx <- DT[,.I[col1 == 1L]], # Retrieve row number 
    set(DT, row_idnx, names(DT), as.list(vec)), 
    DT[col1 == 1L, names(DT) := as.list(vec)] 
) 

Unit: microseconds 
              expr  min  lq  mean median  uq  max neval 
       row_idnx <- DT[, .I[col1 == 1L]] 1255.430 1969.5630 2168.9744 2129.2635 2302.1000 3269.947 100 
    set(DT, row_idnx, names(DT), as.list(vec)) 171.606 207.3235 323.7642 236.6765 274.6515 7725.120 100 
DT[col1 == 1L, `:=`(names(DT), as.list(vec))] 2761.289 2998.3750 3361.7842 3155.8165 3444.6310 13473.081 100