(edit note: I changed the Title to “R: enumerate column combinations of a matrix”, from “R grep: matching a matrix of strings to a list” to better reflect the solution)
I am trying to match a matrix of strings to a list: so that i can ultimately use the matrix as a map in later operations on a data.frame.
This first part works as intended, returning a list of all the possible pairs, triples and quad combinations (though perhaps this approach has created my bind?):
priceList <- data.frame(aaa = rnorm(100, 100, 10), bbb = rnorm(100, 100, 10),
ccc = rnorm(100, 100, 10), ddd = rnorm(100, 100, 10),
eee = rnorm(100, 100, 10), fff = rnorm(100, 100, 10),
ggg = rnorm(100, 100, 10))
getTrades <- function(dd, Maxleg=3)
{
nodes <- colnames(dd)
tradeList <- list()
for (i in 2:Maxleg){
tradeLeg <- paste0('legs',i)
tradeList[[tradeLeg]] <- combn(nodes, i)
}
return(tradeList)
}
tradeCombos <- getTrades(priceList, 4)
I’d now like to turn this list of possible combinations into trades. For example:
> tradeCombos[[1]][,1]
[1] "aaa" "bbb"
Needs to eventually become priceList[,2] - priceList[,1], and so forth.
I have tried a few approaches with grep and similar commands, and feel that i’ve come close with the following:
LocList <- sapply(tradeCombos[[1]], regexpr, colnames(priceList))
However the format is not quite suitable for the next step.
Ideally, LocList[1] would return something like: 1 2
Assuming that the tradeCombos[[1]][,1] == "aaa" "bbb".
Can someone please help?
__
With help from all of the answers below, i’ve now got:
colDiff <- function(x)
{
Reduce('-', rev(x))
}
getTrades <- function(dd, Maxleg=3)
{
tradeList <- list()
for (i in 2:Maxleg){
tradeLeg <- paste0('legs',i)
tradeLegsList <- combn(names(dd), i,
function(x) dd[x], simplify = FALSE)
nameMtx <- combn(names(dd), i)
names(tradeLegsList) <- apply(nameMtx, MARGIN=2,
FUN=function(x) paste(rev(x), collapse='*'))
tradeList[[tradeLeg]] <- lapply(tradeLegsList, colDiff)
}
return(tradeList)
}
tradeCombos <- getTrades(priceList, 4)
This retains the names of the constitutent parts, and is everything I was trying to achieve.
Many thanks to all for the help.
This gets your eventual aim using
lapply,apply, andReduce.combois a column from one of the combo matrices intradeCombos.rev(combo)reverses the column so the last value is first. TheRsyntax for selecting a subset of columns from adata.frameisDF[col.names], sopriceList[rev(combo)]is a subset ofpriceListwith just the columns incombo, in reverse order.data.frames are actually justlists of columns, so any function that’s designed to iterate overlists can be used to iterate over the columns in adata.frame.Reduceis one such function.Reducetakes a function (in this case the subtract function-) and alistof arguments and then successively calls the function on the arguments in thelistwith the results of the previous call, e.g., (((arg1 – arg2) – arg3) – arg4).You rename the columns in
tradeCombosso that the final column names reflect their source with: