【问题标题】:How do I apply a custom function with multiple data.frames as input in R?如何在 R 中应用具有多个 data.frames 的自定义函数作为输入?
【发布时间】:2014-09-02 20:12:35
【问题描述】:

我正在尝试使用自定义函数,该函数从一个 data.frame (raw_DF) 中获取一行数据,并使用来自单独 data.frame (calibrant_DF) 的校准数据,然后计算 Raw12 的校准值。我收到此错误:

cal_DF$Cal_set 中的错误:$ 运算符对原子向量无效 调用自:顶级

apply 函数似乎不喜欢以这种方式将 data.frame 传递给它,所以过去几个小时我一直在试图弄清楚是否可以使用不同的 apply 函数(例如,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 解决方案感兴趣 - 这是我想更好地理解的功能,我的印象是它可以优雅地处理这个问题。

【问题讨论】:

  • 你的函数写得好像参数 cal_DF 是一个 data.frame (可能;可能是其他一些二维对象),但是你将 "calibrant_DF" 传递给它,这是一个原子字符向量,而不是 data.frame。如果您尝试从全局环境中传递对象 calibrant_DF,请不要引用其名称。
  • 在编辑代码以删除这些引号后,我收到一个不同但类似的错误:Error in raw_row$Cal_set : $ operator is invalid for atomic vectors Called from: '[.data.frame'(cal_DF, which(cal_DF$Cal_set == raw_row$Cal_set), )
  • 您能否提供一个您想要的输出示例 - 我不能肯定地说,但我怀疑 apply 是错误的功能,无论您要完成什么。
  • 刚刚在上面添加了想要的结果。

标签: r function dataframe apply


【解决方案1】:

apply 需要一个矩阵 - 如果它得到一个数据框,它将把它转换为一个矩阵。所以你不能依赖$apply

快速将您的代码转换为有效的方法的一种方法是:

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

(我希望输出对你有意义......)

【讨论】:

  • 顺便说一句 .. 如果您使用上述方法,我建议您更改您的函数 - 返回一个向量而不是数据框,例如 outdata&lt;-c(raw=raw12,cal=cal12)。这与sapply 结合使用效果更好,sapply 喜欢将其结果放入矩阵中(强制放入矩阵的数据帧是一种丑陋的数据结构)。或者,您可以使用lapply 而不是sapply,然后使用do.call(rbind, ....) 连接这些部分 - 然后您将获得一个数据框作为输出。我相信plyr 也可以做到,也许用更短的方式。
  • 谢谢,您的解决方案应该可以工作 - 我想要列中的结果,但转置很容易。我试试看。
  • 解决方案效果很好!我只是在输出中添加了一个 data.frame(t()) 包装器,以便完全按照我的意愿得到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-04
  • 2021-09-03
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 2022-01-10
相关资源
最近更新 更多