2014-09-02 69 views
0

我试图使用一个自定义函数,它从一个data.frame(raw_DF)获取一行数据,并使用来自单独data.frame(calibrant_DF)的校准数据,然后计算Raw12的校准值。我收到此错误:如何将多个data.frames作为R中的输入应用自定义函数?

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

看来,应用功能不喜欢有data.frame传递给它的这种方式,所以我已经花了几年时间试图弄清楚,如果我可以使用一个不同的应用函数(例如mapply,lapply)或plyr函数来完成我想要做的事情,但没有任何运气。建议?

示例代码(真正的功能和DF的更为复杂):

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") 

而我所需的输出是一个data.frame(或东西我可以放到一个data.frame)这样的结果:

raw12 cal12 3.3 3.463158 3.1 3.090909 5.1 5.357895 4.2 4.20202

感谢您的任何建议!

编辑 - 解决了,但.... 我会对plyr解决方案感兴趣,如果其他人有一个想法 - 这是一个函数,我想更好地理解,我的印象是,这可能是一个问题优雅地处理。

+0

你的功能被写成如果参数'cal_DF'是' data.frame'(大概;可能是一些其他的二维对象),但是你传递给calicy_DF“',它是一个原子字符矢量,而不是'data.frame'。如果您尝试从全局环境传递对象'calibrant_DF',请不要引用其名称。 – nrussell 2014-09-02 20:19:13

+0

编辑代码以删除这些引号后,我收到一个不同的但类似的错误:'在raw_row $ Cal_set:$运算符中的错误对原子向量无效 调用自:'[.data.frame'(cal_DF,which(cal_DF $ Cal_set == raw_row $ Cal_set), )' – DirtStats 2014-09-02 20:30:40

+0

您能否提供您想要的输出示例 - 我不能肯定地说,但我怀疑'apply'对于您尝试完成的任何操作都是错误的函数。 – nrussell 2014-09-02 20:38:36

回答

1

apply需要一个矩阵 - 如果它获得一个数据帧,它会将其转换为矩阵。所以你不能依靠$apply

One可以快速将代码转换的东西,工作方式是:

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

split(raw_df, rownames(raw_DF))转换raw_DF到一个列表,其中每个组件是只有一个行的数据帧。并且sapply将您的功能应用于每个这样的数据帧。

我所得到的在这个例子是:

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

(我希望输出产生任何意义,你...)

+0

Btw ..如果你使用上面的方法,我建议你改变函数bove - 返回一个向量而不是数据框,就像'outdata <-c(raw = raw12,cal = cal12)'。这与'sapply'结合起来更好,它将结果放入矩阵中(数据帧被强制转换为矩阵是一种丑陋的数据结构)。或者,你可以使用'lapply'而不是'sapply',然后用'do.call(rbind,....)'加入部分 - 然后你得到一个数据帧作为输出。我相信'plyr'也可以做到这一点,也许可以用更短的方式。 – lebatsnok 2014-09-02 20:56:00

+0

谢谢,你的解决方案应该能够工作 - 我想在列中得到结果,但转置很容易。我会给它一个镜头。 – DirtStats 2014-09-02 21:09:58

+0

解决方案效果很好!我只是在输出中添加了一个data.frame(t())包装器,以完全按照我的意愿来获取它。 – DirtStats 2014-09-04 20:43:01

相关问题