Reputation: 197
I'm trying my hand at writing a package for R, I was going to do this in excel but I figured learning how to make a basic package would be interesting, and good knowledge to have.
I've gotten the function working, however each variable has to be referenced as a column form the data set individually eg. DATA$D1 etc. I would like to know how to make it cleaner so the function has data has its own an argument, that way the name of the data set only needs to be given once. In the same way say the aov {stats} package works, where the columns are listed and the data frame is set. AOV example (Val, Location are columns of data set starlings):
aov(Val~Location, data=starlings)
My Function:
#' Run PCQ Density Calculation
#' Take four distance measurements and specified area and estimate density.
#' @param A = Specified Area (i.e. 1m^2 or 1 hectare (10,000 m^2))
#' @param D1 = Quarter 1 Distance
#' @param D2 = Quarter 2 Distance
#' @param D3 = Quarter 3 Distance
#' @param D4 = Quarter 4 Distance
#' @return The density esitmation
#' @export
PCQ <- function(A,D1,D2,D3,D4){
return(A^2/((D1+D2+D3+D4)/4)^2)
}
My Function in use (D1,D2,D3,D4 are columns of the data set dat):
PCQ(1,dat$D1,dat$D2,dat$D3,dat$D4)
I've tried having the function have a variable "D" what would hold the data sets name, then have the $D1 etc. in the function but that didn't work.
PCQ <- function(D,A,D1,D2,D3,D4){
return(A^2/((D$D1+D$D2+D$D3+D$D4)/4)^2)
}
Sorry for the lack of clarity on the first edit.
Upvotes: 1
Views: 98
Reputation: 2584
To pass multiple column names to the function without quoting them we can use advantages of package lazyeval
dat <- as.data.frame(matrix(1:50, ncol = 10, dimnames = list(NULL, paste0("C", 1:10))))
# C1 C2 C3 C4 C5 C6 C7 C8 C9 C10
# 1 1 6 11 16 21 26 31 36 41 46
# 2 2 7 12 17 22 27 32 37 42 47
# 3 3 8 13 18 23 28 33 38 43 48
# 4 4 9 14 19 24 29 34 39 44 49
# 5 5 10 15 20 25 30 35 40 45 50
PCQ <- function(D, A, ...)
{
require("lazyeval")
cols <- lazy_dots(...)
cols_names <- unlist(lapply(cols, function(x) as.character(x$expr)))
return( A^2 / (rowSums(D[,cols_names])/4)^2 )
}
PCQ(dat, 100, C1, C5, C7, C10)
# [1] 16.32486 15.08153 13.97502 12.98596 12.09830
But more beautiful solution may be created with function select
from dplyr
package.
PCQ2 <- function(D, A, ...)
{
require("dplyr")
return( A^2 / (rowSums(select(D, ...))/4)^2 )
}
PCQ2(dat, 100, C1, C5, C7, C10)
# [1] 16.32486 15.08153 13.97502 12.98596 12.09830
Upvotes: 0
Reputation: 54267
Or try this
dat <- data.frame(P.1st = 1:10)
PCQ <- function(df, var1) {
col <- deparse(substitute(var1))
return(cumsum(df[, col]))
}
PCQ(dat, P.1st)
# [1] 1 3 6 10 15 21 28 36 45 55
Upvotes: 1
Reputation: 5555
Try this
PCQ <- function(data,A,D1,D2,D3,D4){
return(A^2/((data[,D1] + data[,D2] + data[,D3] + data[,D4])/4)^2)
}
This function can be used as
PCQ(data = dat,1,"P.1st","P.2nd","P.3rd","P.4th")
Upvotes: 0