2010-04-12 12 views
16

Sto utilizzando la funzione di R "da" per tritare un frame di dati e applicare una funzione di diverse parti, in questo modo:Convertire un "con" oggetto ad un frame di dati in R

pairwise.compare <- function(x) { 
Nright <- ... 
Nwrong <- ... 
Ntied <- ... 
return(c(Nright=Nright, Nwrong=Nwrong, Ntied=Ntied)) 
} 
Z.by <- by(rankings, INDICES=list(rankings$Rater, rankings$Class), FUN=pairwise.compare) 

il risultato (Z.by) simile a questa:

: 4 
: 357 
Nright Nwrong Ntied 
    3  0  0 
------------------------------------------------------------ 
: 8 
: 357 
NULL 
------------------------------------------------------------ 
: 10 
: 470 
Nright Nwrong Ntied 
    3  4  1 
------------------------------------------------------------ 
: 11 
: 470 
Nright Nwrong Ntied 
    12  4  1 

Quello che vorrei è avere questo risultato trasformato in un frame di dati (con le voci NULL non presente) in modo che assomiglia a questo:

Rater Class Nright Nwrong Ntied 
1  4 357  3  0  0 
2 10 470  3  4  1 
3 11 470  12  4  1 

Come faccio?

risposta

8

Considerare utilizzando ddply nel pacchetto plyr invece che dai. Gestisce il lavoro di aggiungere la colonna al tuo dataframe.

16

La funzione by restituisce una lista, in modo da poter fare qualcosa di simile:

data.frame(do.call("rbind", by(x, column, mean))) 
+0

che quasi fa quello che voglio, ho un frame di dati con le colonne Nright, Nwrong e Ntied, ma non produce le colonne Rater e classe. –

+2

Suggerisco di cambiare la funzione 'pairwise.compare' per restituire questi due campi. Altrimenti dovrai usare una routine 'lapply' (o' plyr') per ottenere sia i nomi delle liste che i valori (che è un passo in più). – Shane

+0

Sembra che plyr sia in realtà una soluzione più semplice che in questo caso, non sapevo prima di quel pacchetto. –

3

thread vecchio, ma per chi cerca questo argomento:

analysis = by(...) 
data.frame(t(vapply(analysis,unlist,unlist(analysis[[1]])))) 

unlist() avrà un elemento di una by() uscita (in questo caso, analysis) ed esprimerlo come vettore di nome. vapply() non elencato per tutti gli elemnts di analysis e restituisce il risultato. Richiede un argomento fittizio per conoscere il tipo di output, che è ciò per cui è disponibile lo analysis[[1]]. Potrebbe essere necessario aggiungere un controllo che l'analisi non sia vuota se ciò sarà possibile. Ogni uscita sarà una colonna, quindi t() lo traspone all'orientamento desiderato in cui ogni voce di analisi diventa una riga.

+0

Questa soluzione non funziona se si dispone di tipi misti nel data.frame (come i caratteri in una colonna e i numeri in un'altra), perché si basa su 'vapply'. In questo caso specifico, la soluzione di Shane sopra funziona perfettamente bene però. – Jealie

2

Questo espande la soluzione di Shane dell'utilizzo di rbind(), ma aggiunge anche colonne che identificano i gruppi e rimuove i gruppi NULL - due funzionalità che sono state richieste nella domanda. Utilizzando le funzioni del pacchetto di base, non sono richieste altre dipendenze, ad es. Plyr.

simplify_by_output = function(by_output) { 
    null_ind = unlist(lapply(by_output, is.null)) # by() returns NULL for combinations of grouping variables for which there are no data. rbind() ignores those, so you have to keep track of them. 
    by_df = do.call(rbind, by_output) # Combine the results into a data frame. 
    return(cbind(expand.grid(dimnames(by_output))[!null_ind, ], by_df)) # Add columns identifying groups, discarding names of groups for which no data exist. 
} 
2

Farei

x = by(data, list(data$x, data$y), function(d) whatever(d)) 
array(x, dim(x), dimnames(x)) 
Problemi correlati