2015-03-05 10 views

risposta

9

Al momento, la soluzione è estrarre gli indici e quindi eseguire un compito per riferimento.

idx = DT[, .(idx = .I[c(1L, .N)]), by=class]$idx 
DT[idx, v := NA] 

Cercherò e aggiungi a esempio per il Reference semantics vignetta.

+0

Il secondo comando può essere eseguito con qualcosa come 'set (DT, j =" v ", i = idx, value = NA)', giusto? Sapresti meglio di me se è più veloce. – Frank

+1

@Frank, se lo stai facendo più e più volte, sì 'set()' sarebbe più veloce in quanto non ha il sovraccarico di '[.data.table'. Non dovrebbe importare qui – Arun

1

Con una funzione di supporto è facile

set.na = function(x,y) {x[y] = NA; x} 
DT[, set.na(v,c(1,.N)) , by=class] 
0

Il modo canonico per modificare sottoinsiemi dei dati è quello di utilizzare i per definire il sottoinsieme. Non è possibile utilizzare [ insieme a :=. O creare uno spazio temporaneo i come suggerito da @David Arenburg oppure è possibile creare il vettore finale utilizzando una costruzione c(NA, v[-c(1, .N)], NA).

DT[, v := c(NA, v[-c(1, .N)], NA)[1:.N], by = class] 

Tuttavia, dovresti anche notare che l'ordine delle righe può cambiare quando ad es. impostare una nuova chiave o utilizzare un numero qualsiasi di funzioni. Quindi dovresti stare molto attento con questa operazione.

3

Questo non può essere un one-liner, ma ha 'prima' e 'ultima' nel codice :)

> DT <- data.table(v = rnorm(12), class=rep(1:3, each=4)) 
> setkey(DT, class) 
> classes = DT[, .(unique(class))] 
> DT[classes, v := NA, mult='first'] 
> DT[classes, v := NA, mult='last'] 
> DT 
      v class 
1:  NA  1 
2: -1.8191  1 
3: -0.6355  1 
4:  NA  1 
5:  NA  2 
6: -1.1771  2 
7: -0.8125  2 
8:  NA  2 
9:  NA  3 
10: 0.2357  3 
11: 0.3416  3 
12:  NA  3 
> 

ordine anche conservati per le colonne non chiave. Penso che sia una funzionalità documentata (impegnata a).