如何在函数内部/内部使用?

时间:2011-05-19 15:15:11

标签: r

我很难理解为什么这不起作用。

df <- data.frame(a=1:10, b=1:10)

foo <- function(obj, col) {
   with(obj, ls())
   with(obj, print(col))
}
foo(df, a)
  

[1]“a”“b”

     

print(col)中的错误:找不到对象'a'

如果确实有效:

with(df, print(a))

3 个答案:

答案 0 :(得分:12)

with非常方便,可以提高交互式上下文的可读性,但在编程环境中可能会伤害您的大脑,在这种情境中,您可以在不同的环境中来回传递函数和处理事物。一般来说,在R中,使用符号而不是名称是一种“语义糖”,在交互式使用中方便易读,但在编程时略微弃用[例如$subset])。如果您愿意在使用名称("a")而不是符号(a)时妥协,那么我建议回到更简单的obj[[col]]而不是使用{{ 1}}这里......

所以,作为一个独立的答案:

with

如果您想允许多个列(即字符向量)

foo <- function(object,col) {
   print(names(object))
   print(object[[col]])
}

编辑:在@ hadley的建议下,不要使用foo <- function(object,col) { print(names(object)) print(object[col]) } 函数

(这会将答案打印为数据框,即使选择了一列,也可能不是您想要的那样)。

答案 1 :(得分:4)

传递给函数的任何内容都必须是对象,字符串或数字。这有两个问题:

  1. 在这种情况下,你试图传递“a”作为一个对象,当你真的应该像字符串一样传递它。
  2. with(obj,ls()))将返回函数环境(函数作用域)而不是屏幕,除非你告诉它打印。
  3. 你想要的更像是:

    foo <- function(obj, col) {
           print(with(obj, ls()))
           with(obj, print(obj[[col]]))
        }
    
    foo(df, "a")
    

    或者,如果您只是要查找要打印的一列:

    foo <- function(obj, col) {
               with(obj, print(obj[[col]]))
            }
    
    foo(df, "a")
    

答案 2 :(得分:1)

在函数参数col中,在使用函数之前评估(与交互使用相反)。这里有两个解决这个问题的方法。

foo1 <- function(obj, col) {
          with(obj, print(eval(col)))
        }
foo1(mydf, quote(a))# here you have to remember to quote argument


foo2 <- function(obj, col) {
          col <- as.expression(as.name(substitute(col)))#corrected after DWIN comment
          with(obj, print(eval(col)))
        }
foo2(mydf, a)# this function does all necessary stuff