2013-04-18 26 views
6

ho un frame di dati come questo:r - Come aggiungere indice di riga ad un frame di dati, sulla base di combinazione di fattori

df <- data.frame(
    Dim1 = c("A","A","A","A","A","A","B","B"), 
    Dim2 = c(100,100,100,100,200,200,100,200), 
    Value = sample(1:10, 8) 
     ) 

    Dim1 Dim2 Value 
1 A 100  3 
2 A 100  6 
3 A 100  7 
4 A 100  4 
5 A 200  8 
6 A 200  9 
7 B 100  2 
8 B 200 10 

(La colonna Valore è solo per illustrare che ogni riga è un punto di dati il valore effettivo non ha importanza.) In definitiva, ciò che vorrei fare è tracciare i valori rispetto al loro indice all'interno della serie definita da Dim1 e Dim2. Per questo motivo, penso che bisogno di aggiungere una nuova colonna che contiene gli indici, che sarebbe simile a questa (aggiunte righe vuote tra le righe da rendere evidente ciò che i sottoinsiemi sono):

Dim1 Dim2 Value Index 
1 A 100  1  1 
2 A 100  9  2 
3 A 100  4  3 
4 A 100 10  4 

5 A 200  7  1 
6 A 200  3  2 

7 B 100  5  1 

8 B 200  8  1 

Come faccio a fare questo con eleganza in R? Vengo da Python e il mio approccio predefinito è quello di for-loop sulle combinazioni di Dim1 & Dim2, tenendo traccia del numero di righe in ciascuna e assegnando il massimo incontrato finora ad ogni riga. Ho cercato di capirlo, ma il mio vettore-fu è debole.

+0

E 'ciò che si sta cercando di fare? 'df $ index <- c (1,2,3,4,1,2,1,1)' –

+0

@Jdbaba In questo esempio particolare, sì. Generalmente no, dal momento che ho bisogno di una funzione astratta che funzioni con un data.frame più grande con più variabili fattore, ecc. – user2296603

+0

Dato che questo è stato risposto con successo, c'è un modo in cui il titolo potrebbe essere più informativo? Per me sapere come farlo è di fondamentale importanza e vorrei che le persone potessero trovarlo. – user2296603

risposta

5

questo è probabilmente andare a guardare come barare dal momento che sto passando un vettore in una funzione che ho poi totalmente ignorare se non per ottenere la sua lunghezza:

df$Index <- ave(1:nrow(df), df$Dim1, factor(df$Dim2), FUN=function(x) 1:length(x)) 

La funzione ave restituisce un vettore della stessa lunghezza il suo primo argomento, ma calcolato all'interno di categorie definite da tutti i fattori tra il primo argomento e l'argomento denominato FUN. (Spesso dimentico di mettere FUN = in per la mia funzione e ottenere un messaggio di errore criptico lungo le linee di unique() applies only to vectors, poiché stava provando a determinare quanti valori univoci una funzione anonima possiede e fallisce.

C'è in realtà un altro modo ancora più compatto di esprimere function(x) 1:length(x) utilizzando la funzione di seq_along whch è probabilmente più sicuro in quanto verrebbe a mancare correttamente se superato un vettore di lunghezza pari a zero, mentre il modulo di funzione anonima avrebbe fallito in modo improprio restituendo 1:0 invece di numeric(0):

ave(1:nrow(df), df$Dim1, factor(df$Dim2), FUN=seq_along) 
4

Qui vai usando data.table:

library(data.table) 
df <- data.table(
    Dim1 = c("A","A","A","A","A","A","B","B"), 
    Dim2 = c(100,100,100,100,200,200,100,200), 
    Value = sample(1:10, 8) 
     ) 

df[, index := seq_len(.N), by = list(Dim1, Dim2)] 
+0

usa 'seq_len (.N)' invece di '1: .N' (mentre in questo caso .N sarà sempre 1 o superiore, seq_len è più veloce e più sicuro ingenerale) – mnel

+0

ok, risolto, grazie – eddi

+0

@eddi Grazie, questo fa anche quello di cui ho bisogno! Penso che per ora preferisco la soluzione postata in precedenza perché funziona con data.frames e sono totalmente estraneo a data.tables. – user2296603

0

È questo che stai cercando di ottenere?

library(ggplot2) 
df <- data.frame(
    Dim1 = c("A","A","A","A","A","A","B","B"), 
    Dim2 = c(100,100,100,100,200,200,100,200), 
    Value = sample(1:10, 8) 
) 
df$index <- c(1,2,3,4,1,2,1,1) 

ggplot(df,aes(x=index,y=Value))+geom_point()+facet_wrap(Dim1~Dim2) 

L'uscita è la seguente: enter image description here

+0

In definitiva, si! Tranne che mi trovo a mio agio con ggplot2, ma non so come fare una funzione che ordina automaticamente la colonna Indice. – user2296603

Problemi correlati