2011-05-19 57 views
6

我很努力去理解这是行不通的。如何在功能内使用/内部使用?

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” 的

错误打印(COL):对象 'A' 未找到

如果这样没有问题:

with(df, print(a)) 
+1

这可能会有助于更广泛地了解您正在尝试完成的内容。 – 2011-05-19 15:22:48

回答

12

with更得心应手,在提高可读性交互式上下文,但可能会在编程环境中伤害大脑,在这种编程环境中,来回传递函数并处理不同环境中的事物。一般来说,在R中,使用符号而不是名称是一种“语义糖”,在交互式使用中方便且可读,但对编程适度不赞成[例如$,subset])。如果你愿意,只要使用一个名称("a")妥协,而不是一个符号(a),那么我会建议回落至简单obj[[col]],而不是在这里使用with ...

所以,作为一个自-contained答案:

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

如果你想允许多个列(即特征向量)

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

编辑:refra从使用subset的功能,在@哈德利的建议

(这将打印答案作为数据框,即使选择了单个列,这可能不是你想要的)。

+0

删除了我的回答,因此您可能需要更改引荐。并为警告+1。 – 2011-05-19 15:49:02

+0

感谢您的所有答案。我并不是真的想要打印任何东西,我只是希望能够将该列传递给其他功能。看看像列的变量名称,而不是字符串的函数,我认为这很容易做到这一点。我想我会坚持传递字符串。 :) – rafalotufo 2011-05-20 02:01:30

+0

除了在函数内部使用子集是不好的形式,因为如果列不如您期望的那样您会得到令人困惑的错误消息 - 最好使用直接子集。 – hadley 2011-05-22 17:08:36

4

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

  1. 在这种情况下,你试图传递“a”作为对象,当你真的应该像一个字符串传递它。
  2. with(obj,ls()))将返回到函数环境(函数范围),而不是屏幕,除非您让它打印。

你想要的是更象:

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") 
+0

但这并不是他想要的:他想要打印df $ a。 – 2011-05-19 15:24:03

+0

目前尚不清楚他想印什么。对我来说,看起来他想要打印两行。一个具有obj的colname,另一个具有指定列的内容。 – 2011-05-19 15:29:03

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 
+0

+1用于回答提出的问题,虽然我仍然认为与/ eval /等混乱。用这种方法是一个坏主意...... – 2011-05-19 21:09:23

+0

我无法让第二个人工作。通常当你使用'eval'时,你需要指定一个环境。 – 2011-05-20 04:13:59