Para cada fila en un marco de datos R

Resuelto Carl Coryell-Martin asked hace 54 años • 9 respuestas

Tengo un marco de datos y para cada fila de ese marco de datos tengo que hacer algunas búsquedas complicadas y agregar algunos datos a un archivo.

El marco de datos contiene resultados científicos para pocillos seleccionados de placas de 96 pocillos utilizados en investigación biológica, por lo que quiero hacer algo como:

for (well in dataFrame) {
  wellName <- well$name    # string like "H1"
  plateName <- well$plate  # string like "plate67"
  wellID <- getWellID(wellName, plateName)
  cat(paste(wellID, well$value1, well$value2, sep=","), file=outputFile)
}

En mi mundo procesal, haría algo como:

for (row in dataFrame) {
    #look up stuff using data from the row
    #write stuff to the file
}

¿Cuál es la "forma R" de hacer esto?

Carl Coryell-Martin avatar Jan 01 '70 08:01 Carl Coryell-Martin
Aceptado

Puedes usar la by()función:

by(dataFrame, seq_len(nrow(dataFrame)), function(row) dostuff)

Pero iterar sobre las filas directamente de esta manera rara vez es lo que desea; deberías intentar vectorizar en su lugar. ¿Puedo preguntar qué está haciendo el trabajo real en el bucle?

Jonathan Chang avatar Nov 09 '2009 05:11 Jonathan Chang

Primero, el punto de vista de Jonathan sobre la vectorización es correcto. Si su función getWellID() está vectorizada, entonces puede omitir el ciclo y simplemente usar cat o write.csv:

write.csv(data.frame(wellid=getWellID(well$name, well$plate), 
         value1=well$value1, value2=well$value2), file=outputFile)

Si getWellID() no está vectorizado, entonces la recomendación de uso de Jonathan byo la sugerencia de knguyen applydeberían funcionar.

De lo contrario, si realmente deseas utilizar for, puedes hacer algo como esto:

for(i in 1:nrow(dataFrame)) {
    row <- dataFrame[i,]
    # do stuff with row
}

También puedes intentar utilizar el foreachpaquete, aunque requiere que te familiarices con esa sintaxis. He aquí un ejemplo sencillo:

library(foreach)
d <- data.frame(x=1:10, y=rnorm(10))
s <- foreach(d=iter(d, by='row'), .combine=rbind) %dopar% d

Una última opción es utilizar una función fuera del plyrpaquete, en cuyo caso la convención será muy similar a la función de aplicación.

library(plyr)
ddply(dataFrame, .(x), function(x) { # do stuff })
Shane avatar Nov 09 '2009 14:11 Shane