Para cada fila en un marco de datos R
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?
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?
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 by
o la sugerencia de knguyen apply
deberí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 foreach
paquete, 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 plyr
paquete, 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 })