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

时间:2022-11-17 07:40:01

I'm struggling to understand why does this doesn't work.

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

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"

[1]“a”“b”

Error in print(col) : object 'a' not found

print(col)出错:找不到对象'a'

If this does work:

如果这确实有效:

with(df, print(a))

3 个解决方案

#1


12  

with is handy and improves readability in an interactive context but can hurt your brain in a programming context where you are passing things back and forth to functions and dealing with things in different environments. In general within R, using symbols rather than names is a sort of "semantic sugar" that is convenient and readable in interactive use but mildly deprecated for programming [e.g. $, subset]). If you're willing to compromise as far as using a name ("a") rather than a symbol (a) then I would suggest falling back to the simpler obj[[col]] rather than using with here ...

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

So, as a self-contained answer:

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

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

If you wanted to allow for multiple columns (i.e. a character vector)

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

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

edit: refraining from using subset with a function, at @hadley's suggestion

编辑:在@ hadley的建议中避免使用带有函数的子集

(this will print the answer as a data frame, even if a single column is selected, which may not be what you want).

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

#2


4  

Anything that is passed to a function must be an object, a string or a number. There are two problems with this:

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

  1. In this case you're trying to pass "a" as an object, when you should really be passing it like a string.
  2. 在这种情况下,你试图传递“a”作为一个对象,当你真的应该像字符串一样传递它。

  3. with(obj, ls())) will return to the functions environment (function scoping) and not the screen unless you tell it to print.
  4. with(obj,ls()))将返回函数环境(函数作用域)而不是屏幕,除非你告诉它打印。

What you want is more like:

你想要的更像是:

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

foo(df, "a")

Or if you're only looking for the one column to be printed:

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

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

foo(df, "a")

#3


1  

In function argument col is evaluated before using in function with (that opposite to interactive use). Here you have two solutions to this problem.

函数参数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

#1


12  

with is handy and improves readability in an interactive context but can hurt your brain in a programming context where you are passing things back and forth to functions and dealing with things in different environments. In general within R, using symbols rather than names is a sort of "semantic sugar" that is convenient and readable in interactive use but mildly deprecated for programming [e.g. $, subset]). If you're willing to compromise as far as using a name ("a") rather than a symbol (a) then I would suggest falling back to the simpler obj[[col]] rather than using with here ...

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

So, as a self-contained answer:

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

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

If you wanted to allow for multiple columns (i.e. a character vector)

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

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

edit: refraining from using subset with a function, at @hadley's suggestion

编辑:在@ hadley的建议中避免使用带有函数的子集

(this will print the answer as a data frame, even if a single column is selected, which may not be what you want).

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

#2


4  

Anything that is passed to a function must be an object, a string or a number. There are two problems with this:

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

  1. In this case you're trying to pass "a" as an object, when you should really be passing it like a string.
  2. 在这种情况下,你试图传递“a”作为一个对象,当你真的应该像字符串一样传递它。

  3. with(obj, ls())) will return to the functions environment (function scoping) and not the screen unless you tell it to print.
  4. with(obj,ls()))将返回函数环境(函数作用域)而不是屏幕,除非你告诉它打印。

What you want is more like:

你想要的更像是:

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

foo(df, "a")

Or if you're only looking for the one column to be printed:

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

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

foo(df, "a")

#3


1  

In function argument col is evaluated before using in function with (that opposite to interactive use). Here you have two solutions to this problem.

函数参数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