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
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 ...
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
(this will print the answer as a data frame, even if a single column is selected, which may not be what you want).
In function argument col is evaluated before using in function with (that opposite to 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
Anything that is passed to a function must be an object, a string or a number. There are two problems with this:
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")