【问题标题】:Changing R output object names with function arguments使用函数参数更改 R 输出对象名称
【发布时间】:2013-12-15 00:20:11
【问题描述】:

我是 R 新手,如果我的语言不准确,请原谅(并纠正)我。

我编写了一个程序来加载数据、创建列联表(使用 xtabs)、在其上运行一些外部函数并输出结果表。我已经在我的完整数据集上运行了代码,并且想在我的数据子集上运行相同的代码。我已将代码封装为一个函数,并希望能够传递 子集的名称 (SUBNAM) 和 子集表达式 (SUBEXP ) 作为函数中的参数调用类似:

HCACC <- function (SUBNAM, SUBEXP) {  
   CM.SUBNAM <- as.matrix(
      xtabs(~HC_map+HC_obs, data=VVD
      , drop.unused.levels=FALSE, sparse=TRUE
      , subset=(SUBEXP)
      ) )

   AKw.SUBNAM <- kw(CM.SUBNAM, wtHC)
   USER.SUBNAM <- as.data.frame(AKw.SUBNAM$user.wa)
   write.csv(HCACC.SUBNAM, file="HCACC.SUBNAM.csv", row.names=TRUE)
}

HCACC(2013, Year == 2013)
HCACC(JMDR, Observer == "JMDR")

(最后三行是我想要 SUBNAM 的示例,实际上有 40 个实例)

我希望最终得到 CM.2013、CM.JMDR 等,而不必重复复制/粘贴和查找/替换代码。

似乎必须有一种方法可以做到这一点,但我尝试的方法不起作用,而且我的谷歌搜索没有发现任何问题(但我怀疑我可能一直在问错误的问题)。任何提示或指示将不胜感激。

*EDIT* 澄清一下,我对将子集名称和表达式传递给函数的其他方法持开放态度,而不是作为参数。我只是希望能够在不同的子集上多次重复分析/代码,并相应地命名输出。感谢您的见解!

【问题讨论】:

  • 我对 xtabs 和 kw 函数不太熟悉,但我认为您的 SUBEXP 表达式必须是一个字符。 'Year == 2013' 并不完全是您可以传递给您的函数的参数(我不认为)。您可能必须将其作为字符串传递,然后使用eval(parse(text = SUBEXP))。如果我误解了您的问题,我深表歉意。
  • 我怀疑你会得到任何答案,除非你向人们展示你的输入数据并给他们dput()。问问自己是否有人向您展示了您发布的功能 - 您能否在不查看数据的情况下对其进行解密?
  • 只是为了让您朝着正确的方向前进,当您在函数(或其他地方)中传递 Year == 2013Observer == "JMDR" 之类的东西时,您实际上传递的是一个逻辑向量,其值为 "变量 Year 的每个值是否等于 2013”​​。您可能打算使用函数quoteexpression,但它变得非常坚韧。还有其他方法可以完成相同的任务,但您的目标是什么并不完全清楚。
  • 您可以改用VVD$Year == 2013 使其工作,但这不是一个很好的解决方案。这里真正的问题是您在函数中硬编码了太多东西。而不是硬编码data = VVD,只需跳过子集参数并将所需数据的子集传递给您的函数。这要简单得多。

标签: r function arguments


【解决方案1】:

首先,您的代码中似乎存在错误(错字)。您创建了数据框 USER.SUBNAM,但尝试写出不存在的 HCACC.SUBNAM。此外,您的 cmets 说您想要文件名 CM.2013 和 CM.JMDR,但您的代码似乎正在尝试 HCACC.2013 和 HCACC.JMDR。

看起来您真正需要使用 SUBNAM 的唯一地方是在输出文件名中。函数中的所有变量都是临时变量,每次调用函数时不需要有不同的名称。所以相反,我认为你想要这样的东西:

    HCACC <- function (SUBNAM, SUBEXP) {  
       CM <- as.matrix(xtabs(~HC_map+HC_obs, data=VVD, 
        drop.unused.levels=FALSE, sparse=TRUE,
        subset=(SUBEXP)
          ) )

       AKw <- kw(CM, wtHC)
       HCACC <- as.data.frame(AKw$user.wa)
       write.csv(HCACC, file= paste("HCACC.", SUBNAM, ".csv", sep=""),  
        row.names=TRUE)
    }

    HCACC(2013, Year == 2013)
    HCACC(JMDR, Observer == "JMDR")

【讨论】: