简体   繁体   中英

How do I apply a custom function with multiple data.frames as input in R?

I'm trying to use a custom function that takes a row of data from one data.frame (raw_DF) and uses calibration data from a separate data.frame (calibrant_DF) and then calculates the calibrated value of Raw12. I am getting this error:

Error in cal_DF$Cal_set : $ operator is invalid for atomic vectors Called from: top level

It seems that the apply function doesn't like having a data.frame passed to it this way so I've spent the past few hours trying to figure out if I can use a different apply function (eg mapply, lapply) or a plyr function to accomplish what I'm trying to do but without any luck. Suggestions?

Example Code (real functions and DF's are more complicated):

raw_DF<-data.frame("Cal_set"=c(1,2,1,2),"Raw12"=c(3.3,3.1,5.1,4.2))
calibrant_DF<-data.frame("Cal_set"=c(1,2),"b12"=c(.01,.04),"m12"=c(.95,.99))

apply.cals <- function(raw_row,cal_DF){
  current_cals<-cal_DF[which(cal_DF$Cal_set==raw_row$Cal_set),]
  raw12<-raw_row$Raw12
  cal12<-(raw12-current_cals$b12)/current_cals$m12

  outdata<-data.frame(raw12,cal12)
  return(outdata)
} # End of apply.cals

calibrated_data<-apply(X=raw_DF,MARGIN=1,FUN=apply.cals,cal_DF="calibrant_DF")

And my desired output is a data.frame (or something I can put into a data.frame) of results like this:

raw12 cal12 3.3 3.463158 3.1 3.090909 5.1 5.357895 4.2 4.20202

Thanks for any advice!

EDIT - SOLVED, BUT.... I'd be interested in plyr solutions if anyone else has one in mind - that's a function I'd like to understand better and my impression is that this a problem it could deal with elegantly.

apply expects a matrix - and if it gets a data frame, it will convert it to a matrix. So you can't rely on $ with apply .

One way to quickly convert your code to something that works is:

sapply(split(raw_DF, rownames(raw_DF)), apply.cals, cal_DF=calibrant_DF)

split(raw_df, rownames(raw_DF)) converts raw_DF into a list, where each component is a data frame with just one row. And sapply applies your function to each such data frame.

What i get in this example is:

#       1        2        3        4      
# raw12 3.3      3.1      5.1      4.2    
# cal12 3.463158 3.090909 5.357895 4.20202

(I hope the output makes any sense to you ... )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM