Jeg har en dataramme, og for hver rad i datarammen må jeg gjøre noen kompliserte oppslag og legge til data i en fil.
DataFrame inneholder vitenskapelige resultater for utvalgte brønner fra 96 brønnplater som brukes i biologisk forskning, så jeg vil gjøre noe sånt som:
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)
}
I min prosedyreverden ville jeg gjort noe sånt som: {{{24961}}}:
for (row in dataFrame) {
#look up stuff using data from the row
#write stuff to the file
}
Hva er "R-måten" å gjøre dette på?
Du kan bruke funksjonen by()
:
by(dataFrame, 1:nrow(dataFrame), function(row) dostuff)
Men å iterere over radene direkte på denne måten er sjelden det du ønsker; du bør prøve å vektorisere i stedet. Kan jeg spørre hva det egentlige arbeidet i løkken går ut på?
Du kan prøve dette ved å bruke funksjonen apply()
> d
name plate value1 value2
1 A P1 1 100
2 B P2 2 200
3 C P3 3 300
> f <- function(x, output) {
wellName <- x[1]
plateName <- x[2]
wellID <- 1
print(paste(wellID, x[3], x[4], sep=","))
cat(paste(wellID, x[3], x[4], sep=","), file= output, append = T, fill = T)
}
> apply(d, 1, f, output = 'outputfile')
For det første er Jonathans poeng om vektorisering riktig. Hvis getWellID()-funksjonen er vektorisert, kan du hoppe over løkken og bare bruke cat eller write.csv:
write.csv(data.frame(wellid=getWellID(well$name, well$plate),
value1=well$value1, value2=well$value2), file=outputFile)
Hvis getWellID() ikke er vektorisert, bør Jonathans anbefaling om å bruke by
eller knguyens forslag om apply
fungere.
Ellers, hvis du virkelig ønsker å bruke for
, kan du gjøre noe slikt:
for(i in 1:nrow(dataFrame)) {
row <- dataFrame[i,]
# do stuff with row
}
Du kan også prøve å bruke foreach
-pakken, selv om det krever at du blir kjent med den syntaksen. Her er et enkelt eksempel:
library(foreach)
d <- data.frame(x=1:10, y=rnorm(10))
s <- foreach(d=iter(d, by='row'), .combine=rbind) %dopar% d
Et siste alternativ er å bruke en funksjon fra plyr
-pakken, og i så fall vil konvensjonen være svært lik apply-funksjonen.
library(plyr)
ddply(dataFrame, .(x), function(x) { # do stuff })