如何将数据框附加到功能的本地环境?

时间:2014-08-22 12:39:27

标签: r

问:R中,如何将数据框作为参数传递给函数并将该数据框附加到函数的本地环境?

这是一个玩具示例:

dat <- data.frame(a = "text1", b = "text2")

fn <- function(df, first, last) {
    ## how do I set up the environment here?
    paste(first, last, sep = " ")
}

fn(df = dat, first = a, last = b) # should return "text1 text2"

也就是说,在函数内部,我希望能够直接引用参数firstlast,它们自己引用数据框dat中的命名列,我已将其作为参数df传递给函数。

这个问题的答案可能很简单(如果是这样道歉),但R环境让我的头脑爆炸。

(澄清一下:我知道attach以及它所带来的所有恐怖;我正在试图弄清楚如何操纵本地环境,但我不确定适当的动词是什么。)

2 个答案:

答案 0 :(得分:2)

我真的建议这样做:

dat <- data.frame(a = "text1", b = "text2", stringsAsFactors=FALSE)

fn <- function(df, first, last) {
  paste(df[, c(first, last)], collapse = " ")
}
fn(df = dat, first = "a", last = "b") 

从长远来看,它将为您节省许多难以发现的错误。

TL; DR:永远不要使用attach

答案 1 :(得分:1)

在实现函数时,操作本地环境并将参数作为符号而不是字符值传递会使事情变得非常混乱。在交互式工作时,拥有改变环境和使用with()等功能的自由是很好的,但是当你考虑编写一个函数时,由于函数(理论上)赢得了这个函数,因此通常没那么重要。经常改变。所以这里有一些实现该功能的方法。第一个建议使用字符

fn1<- function(df, first, last) {
    first = df[[first]]
    last = df[[last]]
    paste(first, last, sep = " ")
}
fn1(df = dat, first = "a", last = "b")

fn2<- function(df, first, last) {
   evalq({
    paste(first, last, sep = " ")
   }, list2env(list(first=df[[first]], last=df[[last]])))
}
fn2(df = dat, first = "a", last = "b")

然后如果你想传递符号

fn3<- function(df, first, last) {
    first = df[[deparse(substitute(first))]]
    last = df[[deparse(substitute(last))]]
    paste(first, last, sep = " ")
}
fn3(df = dat, first = a, last = b)

fn4<- function(df, first, last) {
   first <- substitute(first)
   last <- substitute(last)
   eval(bquote({
    paste(.(first), .(last), sep = " ")
   }),df)
}
fn4(df = dat, first = a, last = b)