How to use inside / inside function?

I am trying to understand why this is not working.

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 error (col): object 'a' not found

If this works:

 with(df, print(a)) 
+6
source share
3 answers

with convenient and improves readability in an interactive context, but it can damage your brain in a programming context where you pass things back and forth through functions and do things in different environments. In the general case, inside R, the use of symbols, rather than names, is a kind of “semantic sugar” that is convenient and readable in interactive use, but mildly outdated for programming [for example, $ , subset ]). If you want to compromise using the name ( "a" ) rather than the character ( a ), I would suggest returning to the simpler obj[[col]] rather than using with here ...

So, as a standalone answer:

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

If you want to allow multiple columns (i.e. character vector)

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

edit : refrain from using subset with function suggested by @hadley

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

+12
source

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

  • In this case, you are trying to pass "a" as an object when you really need to pass it as a string.
  • c (obj, ls ())) will return to the environment of functions (the scope of the function), and not to the screen if you do not inform about it for printing. A.

What do you like more:

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

Or if you are looking for only one column to print:

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

In the function argument, col is computed before being used in function c (which is the opposite of interactive use). Here you have two solutions to this problem.

 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
source

Source: https://habr.com/ru/post/888550/


All Articles