r - Simplify ave() or aggregate() with several inputs -
how can write in 1 line?
mydata "zoo" series, limit numeric vector of same size
tmp <- ave(coredata(mydata), as.date(index(mydata)), fun = function(x) cummax(x)-x) tmp <- (tmp < limit) final <- ave(tmp, as.date(index(mydata)), fun = function(x) cumprod(x)) i've tried use 2 vectors argument ave(...) seems accept 1 if join them matrix.
this example, other function use.
here need compare value of cummax(mydata)-mydata numeric vector , once surpasses i'll keep zeros till end of day. cummax calculated beginning of each day.
if limit single number instead of vector (with different possible numbers) write it:
ave(coredata(mydata), as.date(index(mydata)), fun = function(x) cumprod((cummax(x) - x) < limit)) but can't introduce there vector longer x (it should have same length each day) , don't know how introduce argument in ave().
seems routine imposes intraday stoploss based on maxdrawdown. assume want able pass in variable limit second argument aggregation function takes 1 function due way ave works.
if putting in 1 line not absolute must, can share function i've written generalizes aggregation via "cut variables". here's code:
mtapplylist2 <- function(t, idx, def, moreargs=null, ...) { if(mode(def) != "list") { cat("definition must list type\n"); return(null); } <- c(); colnames <- names(def); ( in 1:length(def) ) { def <- def[[i]]; func <- def[1]; if(mode(func) == "character") { func <- get(func); } cols <- def[-1]; # build argument called arglist <- list(); arglist[[1]] <- func; for( j in 1:length(cols) ) { col <- cols[j]; grp <- split(t[,col], idx); arglist[[1+j]] <- grp; } arglist[["moreargs"]] <- moreargs; v <- do.call("mapply", arglist); # print(class(v)); print(v); if(class(v) == "matrix") { <- cbind(a, as.vector(v)); } else { <- cbind(a, v); } } colnames(a) <- colnames; return(a); } and can use this:
# assuming have data in data.frame df <- data.frame(date=rep(1:10,10), ret=rnorm(100), limit=rep(c(0.25,0.50),50)) dfunc <- function(x, ...) { return(cummax(x)-x ) } pfunc <- function(x,y, ...) { return((cummax(x)-x) < y) } # assumes have function declared in same namespace def <- list( "drawdown" = c("dfunc", "ret"), "hasdrawdown" = c("pfunc", "ret", "limit") ); # r console > def <- list("drawdown" = c("dfunc", "ret"),"happened" = c("pfunc","ret","limit")) > dim( mtapplylist2(df, df$date, def) ) [1] 100 2 notice "def" variable list containing following items:
- computed column name
- vector arg function name string
- name of variable in input data.frame inputs function
if @ guts of "mtapplylist2" function, key components "split" , "mapply". these functions sufficiently fast (i think split implemented in c).
this works functions requiring multiple arguments, , functions returning vector of same size or aggregated value.
try out , let me know if solves problem.
Comments
Post a Comment