2015-11-22 12 views
5

dal mio semplice data.table, per esempio, in questo modo:errore "oggetto 'ansvals' non trovato" - cosa significa?

dt1 <- fread(" 
col1 col2 col3 
AAA ab cd 
BBB ef gh 
BBB ij kl 
CCC mn nm") 

Sto creando nuova tabella, ad esempio, in questo modo:

dt1[, 
    .(col3, new=.N), 
    by=col1] 

> col1 col3 new 
>1: AAA cd 1 
>2: BBB gh 2 
>3: BBB kl 2 
>4: CCC op 1 

questo funziona bene quando indico i nomi delle colonne in modo esplicito . Ma quando li ho nelle variabili e cerco di usare with=F, questo dà un errore:

colBy <- 'col1' 
colShow <- 'col3' 

dt1[, 
    .(colShow, 'new'=.N), 
    by=colBy, 
    with=F] 
# Error in `[.data.table`(dt1, , .(colShow, new = .N), by = colBy, with = F) : object 'ansvals' not found 

non ho trovato alcuna informazione su questo errore finora.

risposta

7

Il motivo per cui si stanno ottenendo questo messaggio di errore è che quando si utilizza with=FALSE dici data.table per trattare j come se si trattasse di un dataframe. Pertanto si aspetta che un vettore di nomi di colonne e non di un'espressione sia valutato in j come new=.N.

Dalla documentazione di ?data.table su with:

By default with=TRUE and j is evaluated within the frame of x; column names can be used as variables. When with=FALSE j is a character vector of column names or a numeric vector of column positions to select, and the value returned is always a data.table.

Quando si utilizza with=FALSE, è necessario selezionare i columnnames in j senza . prima () in questo modo: dt1[, (colShow), with=FALSE]. Altre opzioni sono dt1[, c(colShow), with=FALSE] o dt1[, colShow, with=FALSE]. Lo stesso risultato può essere ottenuto utilizzando dt1[, .(col3)]

Riassumendo: with = FALSE è usato per selezionare le colonne della data.frame modo. Quindi, dovresti farlo allora come tale.

anche utilizzando by = colBy si sta dicendo data.table per valutare j che è in contraddizione con with = FALSE.

Dalla documentazione di ?data.table su j:

A single column name, single expresson of column names, list() of expressions of column names, an expression or function call that evaluates to list (including data.frame and data.table which are lists, too), or (when with=FALSE) a vector of names or positions to select.

j is evaluated within the frame of the data.table; i.e., it sees column names as if they are variables. Use j=list(...) to return multiple columns and/or expressions of columns. A single column or single expression returns that type, usually a vector. See the examples.

V. anche 1.d and 1.g of the introduction vignette di data.table.


ansvals è un nome usato in data.table interni. Potete vedere dove appare nel codice utilizzando Ctrl +f (Windows) o cmd + f (MacOS) here.

+0

grazie per la spiegazione! In realtà significa che non c'è modo di usare 'by =' quando i nomi delle colonne sono memorizzati in variabili? –

+0

@VasilyA Questo è certamente possibile, ma devi farlo nel modo corretto. Vedi [qui] (http://stackoverflow.com/questions/32940580/convert-some-column-classes-in-data-table/32942319#32942319) o [qui] (http://stackoverflow.com/questions/ 33772830/how-to-set-multiple-columns-and-selected-rows-in-data-table-to-value-from-other/33774525 # 33774525) per esempi. Potresti anche voler leggere la [guida introduttiva] (https://github.com/Rdatatable/data.table/wiki/Getting-started) – Jaap

+0

beh, in quegli esempi 'by =' non è usato affatto, questo lo rende piuttosto diverso ... Leggerò di nuovo la guida alle operazioni preliminari e magari pubblicheremo una domanda separata che specifica di cosa esattamente ho bisogno. –

1

L'errore object 'ansvals' not found mi sembra un errore. Dovrebbe essere un messaggio utile o semplicemente funzionare. Ho archiviato issue #1440 collegando a questa domanda, grazie.

Jaap è completamente corretto.Sulla scia la sua risposta, è possibile utilizzare get() in j come questo:

dt1 
# col1 col2 col3 
#1: AAA ab cd 
#2: BBB ef gh 
#3: BBB ij kl 
#4: CCC mn nm 
colBy 
#[1] "col1" 
colShow 
#[1] "col3" 
dt1[,.(get(colShow),.N),by=colBy] 
# col1 V1 N 
#1: AAA cd 1 
#2: BBB gh 2 
#3: BBB kl 2 
#4: CCC nm 1 
+1

grazie Matt! Stavo per pubblicare una domanda che mi chiedeva se get() potrebbe essere una buona soluzione :) –