ramhiser / pocketknife

A collection of useful utility functions in R
Other
3 stars 1 forks source link

Add utility function to simplify Box-Cox transformation #1

Open ramhiser opened 10 years ago

ramhiser commented 10 years ago

The car package provides the capability to employ the Box-Cox transformation to a positive numeric vector (if negative, there is the Yeo-Johnson transformation). The downside is that a linear model has to be fit, and the API is tedious.

For the most common case of simply transforming a vector, a simple interface is desirable.

ramhiser commented 10 years ago

I've implemented both the Box-Cox and Yeo-Johnson transformations. However, I'm having silly NAMESPACE issues with the car package. Here's a dump from the unit tests:

 Testing pocketknife
 Box-Cox Transformation : 123
 Pretty cuts with cut_pretty : .

 1. Error: Box-Cox transformation works with a numeric vector -------------------
 object 'bcPower' of mode 'function' was not found
 1: withCallingHandlers(eval(code, new_test_environment), error = capture_calls)
 2: eval(code, new_test_environment)
 3: eval(expr, envir, enclos)
 4: boxcox_transform(x, family = "bcPower") at test-box-cox.r:7
 5: car::boxCox(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...) at /Users/ramhiser/Dropbox/blacklocus/code/pocketknife/R/boxcox.r:26
 6: boxCox.formula(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...)
 7: NextMethod()
 8: boxCox.default(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...)
 9: match.fun(family)
 10: get(as.character(FUN), mode = "function", envir = envir)

 2. Error: Yeo-Johnson transformation works with a negative numeric vector ------
 object 'yjPower' of mode 'function' was not found
 1: withCallingHandlers(eval(code, new_test_environment), error = capture_calls)
 2: eval(code, new_test_environment)
 3: eval(expr, envir, enclos)
 4: boxcox_transform(x, family = "yjPower") at test-box-cox.r:24
 5: car::boxCox(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...) at /Users/ramhiser/Dropbox/blacklocus/code/pocketknife/R/boxcox.r:26
 6: boxCox.formula(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...)
 7: NextMethod()
 8: boxCox.default(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...)
 9: match.fun(family)
 10: get(as.character(FUN), mode = "function", envir = envir)

 3. Error: Inverse Box-Cox transformation works ---------------------------------
 object 'bcPower' of mode 'function' was not found
 1: withCallingHandlers(eval(code, new_test_environment), error = capture_calls)
 2: eval(code, new_test_environment)
 3: eval(expr, envir, enclos)
 4: boxcox_transform(x, family = "bcPower") at test-box-cox.r:39
 5: car::boxCox(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...) at /Users/ramhiser/Dropbox/blacklocus/code/pocketknife/R/boxcox.r:26
 6: boxCox.formula(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...)
 7: NextMethod()
 8: boxCox.default(x ~ 1, data = df, family = family, plotit = plot, interp = TRUE, ...)
 9: match.fun(family)
 10: get(as.character(FUN), mode = "function", envir = envir)

 >
ramhiser commented 10 years ago

I'd like to split up the Box-Cox and Yeo-Johnson transformations into two separate functions: box_cox and yeo_johnson. Given that box_cox requires positive values, an error should be thrown with a recommendation to use yeo_johnson instead.