2010-08-13 17 views
10

Supongamos que tengo una trama de datos con las columnas c1, ..., cn y una función f que toma en las columnas de esta trama de datos como argumentos. ¿Cómo puedo aplicar f a cada fila del marco de datos para obtener un nuevo marco de datos?mapeo sobre las filas de una trama de datos

Por ejemplo,

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 

¿Cómo se hace esto? Supongo que es algo parecido a {s, l, t} aplicar (x, f), pero no puedo resolverlo.

+1

así que, al final, ¿no hay una manera directa de mapear las filas? No puedo creerlo – nicolas

Respuesta

11

como @greg points out, paste() puede hacer esto. Sospecho que su ejemplo es una simplificación de un problema más general. Después de luchar con esto en el pasado, as illustrated in this previous question, terminé usando el paquete plyr para este tipo de cosas. plyr hace mucho más, pero para estas cosas es fácil:

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

que querrá cambiar el nombre de las columnas de salida, estoy seguro

Así, mientras yo estaba escribiendo esto, @joshua mostró una alternativa método que usa ddply. La diferencia en mi ejemplo es que adply trata el marco de datos de entrada como una matriz. adply no usa la variable "agrupar por" row que creó @joshua. Cómo lo hizo es exactamente cómo lo estaba haciendo hasta que Hadley me indicó el enfoque adply(). En la pregunta antes mencionada.

+0

Gracias por indicarme 'adply' (a través de Hadley). ;-) –

+1

Puede simplificar esto con 'transform' o' summarize': 'adply (x, 1, resumir, pegar (letra, número, sep =" "))' – JoFrhwld

+0

¡Impresionante, gracias! Sí, mi ejemplo fue solo un ejemplo de juguete. Miré plyr + remodelar hace un tiempo, y no lo entendí = (, pero definitivamente voy a tener que echar un vistazo de nuevo. – Brett

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

¡Esta es la manera en que lo habría hecho! Es casi como si hubiéramos sido asesorados por el mismo maestro de R ;-) – Vince

1

creo que estabas pensando en algo como esto, pero tenga en cuenta que la familia de funciones apply no vuelven data.frames. También intentarán forzar su data.frame a una matriz antes de aplicar la función.

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

Por lo que puede estar más interesado en ddply del paquete 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 
Cuestiones relacionadas