JimmyTheRobot
JimmyTheRobot

Reputation: 3

Reference vector from data frame using custom function

I'm trying to call a vector "a" from a data frame "df" using a function. I know I could do this just fine with the following:

> df$a
[1] 1 2 3

But I'd like to use a function where both the data frame and vector names are input separately as arguments. This is the best that I've come up with:

show_vector <- function(data.set, column) {
  data.set$column
}

But here's how it goes when I try it out:

> show_vector(df, a)
NULL

How could I change this function in order to successfully reference vector df$a where the names of both are input to a function as arguments?

Upvotes: 0

Views: 195

Answers (4)

jdobres
jdobres

Reputation: 11957

It's actually possible to do this without passing the column name as a string (in other words, you can pass in the unquoted column name:

show_vector <- function(data.set, column) {
  eval(substitute(column), envir = data.set)
}

Usage example:

df <- data.frame(a = 1:3, b = 4:6)

show_vector(df, b)
# 4 5 6

Upvotes: 2

Onyambu
Onyambu

Reputation: 79238

You can use substitute to capture the input vector name as it is then use `as.character to make it as a character.

show_vector <- function(data.set, column) {
  data.set[,as.character(substitute(column))]
}

Now lets take a look:

(dat=data.frame(a=1:3,b=4:6,c=10:12))
  a b  c
1 1 4 10
2 2 5 11
3 3 6 12

show_vector(dat,a)
[1] 1 2 3

show_vector(dat,"a")
[1] 1 2 3

It works.

we can also write a simple one where we just input a character string:

show_vector1 <- function(data.set, column) {
   data.set[,column]
 }

 show_vector1(dat,"a")
[1] 1 2 3

Although this will not work if the column name is not a character:

show_vector1(dat,a)

 **Show Traceback
 Rerun with Debug
 Error in `[.data.frame`(data.set, , column) : undefined columns selected** 

Upvotes: 1

Gautam
Gautam

Reputation: 2753

Your code would work if you only put the column name in quotes i.e. show_vector(df, "a")

Other multiple ways to do this:

Using base functionality

func <- function(df, cname){
  return(df[, grep(cname, colnames(df))])
}

Or even

func <- function(df, cname){
  return(df[, cname])
}

Upvotes: 1

Punintended
Punintended

Reputation: 737

I've wondered about this kind of thing a lot in the past and haven't found an easy fix. The best I've come up with is this:

df <- data.frame(c(1, 2, 3), c(4, 5, 6))
colnames(df) <- c("A", "B")

test <- function(dataframe, columnName) {
  return(dataframe[, match(columnName, colnames(dataframe))])
}
test(df, "A")

Upvotes: 1

Related Questions