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

Popular posts from this blog

ruby - When to use an ORM (Sequel, Datamapper, AR, etc.) vs. pure SQL for querying -

php - PHPDoc: @return void necessary? -

c++ - Convert big endian to little endian when reading from a binary file -