2010-08-13 20 views
10

Supponiamo di avere un frame di dati con le colonne c1, ..., cn e una funzione f che contiene le colonne di questo frame di dati come argomenti. Come posso applicare f a ciascuna riga del frame di dati per ottenere un nuovo frame di dati?mappatura sopra le righe di un frame di dati

Per esempio,

x = data.frame(letter=c('a','b','c'), number=c(1,2,3)) 
# x is 
# letter | number 
#  a | 1 
#  b | 2 
#  c | 3 

f = function(letter, number) { paste(letter, number, sep='') } 

# desired output is 
# a1 
# b2 
# c3 

Come posso fare questo? Immagino che sia qualcosa sulla falsariga di {s, l, t} apply (x, f), ma non riesco a capirlo.

+1

quindi, alla fine, non esiste un modo diretto per mappare su file? non posso crederci – nicolas

risposta

11

come @greg indica, pasta() può farlo. Sospetto che il tuo esempio sia una semplificazione di un problema più generale. Dopo aver lottato con questo in passato, as illustrated in this previous question, ho finito per usare il pacchetto plyr per questo tipo di cose. plyr fa molto di più, ma per queste cose è facile:

> require(plyr) 
> adply(x, 1, function(x) f(x$letter, x$number)) 
    X1 V1 
1 1 a1 
2 2 b2 
3 3 c3 

ti consigliamo di rinominare le colonne di output, sono sicuro che

Così, mentre stavo scrivendo questo, @joshua ha mostrato un'alternativa metodo usando ddply. La differenza nel mio esempio è che adply considera il frame di dati di input come una matrice. adply non utilizza la variabile "group by" row creata da @joshua. Come ha fatto è esattamente come lo stavo facendo fino a quando Hadley non mi ha indicato l'approccio adply(). Nella domanda di cui sopra.

+0

Grazie per avermi indicato 'adply' (via Hadley). ;-) –

+1

Puoi semplificarlo con 'transform' o' riepilogo ': 'adply (x, 1, riepiloga, incolla (lettera, numero, sep =" "))' – JoFrhwld

+0

Impressionante, grazie! Sì, il mio esempio era solo un esempio di giocattolo. Ho guardato plyr + reshape un po 'di tempo fa, e non l'ho capito = (, ma dovrò sicuramente dare un'altra occhiata. – Brett

6
paste(x$letter, x$number, sep = "") 
+0

Questo è il modo in cui l'avrei fatto! È quasi come se fossimo stati seguiti dallo stesso maestro R ;-) – Vince

1

penso che stavi pensando di qualcosa di simile, ma si noti che la apply famiglia di funzioni non ritornano data.frames. Proveranno anche a forzare il tuo data.frame su una matrice prima di applicare la funzione.

apply(x,1,function(x) paste(x,collapse="")) 

Quindi si può essere più interessati a ddply dal pacchetto plyr.

> x$row <- 1:NROW(x) 
> ddply(x, "row", function(df) paste(df[[1]],df[[2]],sep="")) 
    row V1 
1 1 a1 
2 2 b2 
3 3 c3 
Problemi correlati