【问题标题】:stored values within a custom function在自定义函数中存储值
【发布时间】:2011-02-11 19:25:45
【问题描述】:

我的程序需要一个 data.frame 并处理数字。在某一时刻,来自第 j 列的值乘以预定义的值,该值取决于列名(实际上是物种名称 - 它是生态索引)。到目前为止,我一直在通过第二个 data.frame 通过匹配列名来提供这些值。在函数中集成固定变量值的有效方法是什么?我希望我的程序尽可能可移植,而不需要第二个 data.frame 文件。

编辑

这就是函数。我正在尝试改进第二行(索引

macroIndex <- function(obj, index) {
    index <- read.table("conv.csv", header=T, dec=",")
    a <- c()
    b <- names(obj)
    for (i in 2:length(obj)) {
        obj[i] <- obj[i] * index[which(index==b[i]), 2]
    }
    obj
}

我尝试了另一个解决方案,虽然它可能看起来不太漂亮,但它可以完成工作。我使用 dput(index) 并创建一个永久对象,然后将其插入到我的函数中。

【问题讨论】:

  • 我首先想到如何将所有这些集成到一个紧凑的内托鱼雷形式中是一个小包装。最后,这就是我最终可能会做的事情。
  • 这可能是最优雅的解决方案,这样您就可以在包中包含您的索引数据框,只需记住记录它。

标签: function r dataframe


【解决方案1】:

为什么不将第二个数据框作为参数包含在您的函数调用中,然后检查它是否已给出,如果没有,请手动创建它,这样代码可以适用于与您当前所做的数据集匹配的数据集,但可以更改以匹配新数据集。

类似的东西(对不起,我不在我的电脑上,所以这是未经测试的)

macroIndex <- function(obj, index) {
  if(!exists(index)) {
    index <- data.frame(# contents of the default data frame here )
  }
  a <- c()
  b <- names(obj)
  for (i in 2:length(obj)) {
      obj[i] <- obj[i] * index[which(index==b[i]), 2]
  }
  return(obj)
}

【讨论】:

  • 这是我正在考虑的选项之一。我想要做的是让函数接受尽可能少的参数,以便移植给对 R 不太了解的人。目前我不认为这是一个很大的障碍,但会继续记住它。
【解决方案2】:

您可以使用 R 的词法作用域来定义一个函数 function_maker,它返回您想要的函数 func。创建映射向量的代码仅在调用function_maker 时调用,而不是在调用func 时调用。 mapping 也归 func 所有,因为您的代码的其他部分无法更改它。

dat <- data.frame(a=c(1,2,3),b=c(3,2,0),c=c(5,6,4))

function_maker <- function(){
    mapping <- c(a=4,b=2,c=5)
    function(df){
        for(i in 1:ncol(df)) df[,i] <- df[,i] * mapping[[colnames(df)[i]]]
        return(df)
    }
}

func <- function_maker()

func(dat)

【讨论】:

    【解决方案3】:

    嗯,你需要将你的列名映射到另一个值,所以你必须以某种方式存储它。我会说命名列表将是一种更合适的数据结构,尽管归根结底它并没有太大的区别。

    以下是一些示例数据:

    df <- data.frame(a=1:5, b=2:6)
    mapping <- list(a=3, b=4)
    

    这是一个使用列表的简单示例:

    for(i in 1:ncol(df)) df[,i] <- df[,i] * mapping[[colnames(df)[i]]]
    

    关于 Tal 对使用矩阵的建议:只要您的数据框中的每个值都属于同一类型,这是正确的。如果您有混合类型,那么您需要坚持使用数据框。

    【讨论】:

    • 无循环:df[,] &lt;- lapply(names(df), function(i) df[[i]] * mapping[[i]])
    【解决方案4】:

    1) 考虑移动到矩阵而不是 data.frame - 以获得更快的结果。

    2) 你能提供一些简单的代码来解释你想要实现的目标吗?

    【讨论】:

    • 我已经更新了我的帖子并包含了该功能。我怀疑将用于计算此生态指数的 data.frames 不会增长到足以导致速度问题。