1

I'm trying to use a generic function to operate on each column of a data frame where the operation will vary depending on the class of the column.

I'm having trouble giving the function access to the names of the columns while also dispatching the columns to the correct method.

df <- data.frame(f1 = factor(rep(1:3, 2)))

myfun <- function(x){
  UseMethod("myfun", x)
}

myfun.factor <- function(x){
  print("Using factor method")
  print(names(x))
  print(class(x))
}

myfun.default <- function(x){
  print("Using default method")
  print(names(x))
  print(class(x))
}

Applying as a list gives the correct dispatch but strips the names from the columns

library(plyr)
l_ply(df, myfun)
[1] "Using factor method"
NULL
[1] "factor"

Applying as an array retains the names but doesn't give the correct names

a_ply(df, 2, myfun)
[1] "Using default method"
[1] "f1"
[1] "data.frame"

Is there a neat way to get the best of both or am I stuck with the method described in the answer to this question?

Community
  • 1
  • 1
NGaffney
  • 1,542
  • 1
  • 15
  • 16

1 Answers1

0

I wasn't able to find a direct solution to this question, however I did find a work around I'm fairly happy with. I used an intermediary function which takes the column passed to it by a*ply and passes an unlisted form and it's name to the generic function.

myfun2 <- function(x, x_name){
  UseMethod("myfun2", x)
}

myfun2.factor <- function(x, x_name){
  print("Using factor method")
  print(x_name)
  print(class(x))
  return(NULL)
}

myfun2.default <- function(x, x_name){
  print("Using default method")
  print(x_name)
  print(class(x))
  return(NULL)
}

dispatch_fun <- function(x){
  myfun2(unlist(x), names(x))
}

a_ply(df, 2, dispatch_fun)
## [1] "Using factor method"
## [1] "f1"
## [1] "factor"
NGaffney
  • 1,542
  • 1
  • 15
  • 16