Questa è molto simile a una domanda che applica una funzione comune a più colonne di data.table
uning .SDcols
answered thoroughly here.Applicare la funzione su un sottoinsieme di colonne (.SDcols) mentre si applica una funzione diversa su un'altra colonna (all'interno dei gruppi)
La differenza è che mi piacerebbe applicare contemporaneamente una funzione diversa su un'altra colonna che non fa parte del sottoinsieme .SD
. I post un semplice esempio di seguito per mostrare il mio tentativo di risolvere il problema:
dt = data.table(grp = sample(letters[1:3],100, replace = TRUE),
v1 = rnorm(100),
v2 = rnorm(100),
v3 = rnorm(100))
sd.cols = c("v2", "v3")
dt.out = dt[, list(v1 = sum(v1), lapply(.SD,mean)), by = grp, .SDcols = sd.cols]
restituisce il seguente errore:
Error in `[.data.table`(dt, , list(v1 = sum(v1), lapply(.SD, mean)), by = grp,
: object 'v1' not found
Ora, questo ha un senso perché la colonna v1
non è incluso nel sottoinsieme di colonne che deve essere valutato per primo. Così ho esplorato ulteriormente includendo nel mio sottoinsieme delle colonne:
sd.cols = c("v1","v2", "v3")
dt.out = dt[, list(sum(v1), lapply(.SD,mean)), by = grp, .SDcols = sd.cols]
Ora, questo non causa un errore, ma fornisce una risposta contenente 9 righe (per 3 gruppi), con la somma ripetuta tre volte nella colonna V1
e i mezzi per tutti e 3 colonne (come previsto, ma non voluto) poste in V2
come illustrato di seguito:
> dt.out
grp V1 V2
1: c -1.070608 -0.0486639841313638
2: c -1.070608 -0.178154270921521
3: c -1.070608 -0.137625003604012
4: b -2.782252 -0.0794929150464099
5: b -2.782252 -0.149529237116445
6: b -2.782252 0.199925178109264
7: a 6.091355 0.141659419355985
8: a 6.091355 -0.0272192037753071
9: a 6.091355 0.00815760216214876
Soluzione Soluzione utilizzando 2 passi
Chiaramente è possibile risolvere il problema in più passaggi calcolando la mean
dal gruppo per il sottoinsieme di colonne e di unirsi al sum
dal gruppo per la singola colonna come segue:
dt.out1 = dt[, sum(v1), by = grp]
dt.out2 = dt[, lapply(.SD,mean), by = grp, .SDcols = sd.cols]
dt.out = merge(dt.out1, dt.out2, by = "grp")
> dt.out
grp V1 v2 v3
1: a 6.091355 -0.0272192 0.008157602
2: b -2.782252 -0.1495292 0.199925178
3: c -1.070608 -0.1781543 -0.137625004
sono sicuro che è una cosa abbastanza semplice I Mi manca, grazie in anticipo per qualsiasi consiglio.
il fatto che la prima espressione non funzioni è un bug imo, quindi per favore invia un bug report – eddi