Brigid Mooney
2008-Dec-22 20:20 UTC
[R] How can I avoid nested 'for' loops or quicken the process?
Hi All,
I'm still pretty new to using R - and I was hoping I might be able to get
some advice as to how to use 'apply' or a similar function instead of
using
nested for loops.
Right now I have a script which uses nested for loops similar to this:
i <- 1
for(a in Alpha) { for (b in Beta) { for (c in Gamma) { for (d in Delta) {
for (e in Epsilon)
{
Output[i] <- MyFunction(X, Y, a, b, c, d, e)
i <- i+1
}}}}}
Where Output[i] is a data frame, X and Y are data frames, and Alpha, Beta,
Gamma, Delta, and Epsilon are all lists, some of which are numeric, some
logical (TRUE/FALSE).
Any advice on how to implement some sort of solution that might be quicker
than these nested 'for' loops would be greatly appreciated.
Thanks!
[[alternative HTML version deleted]]
Charles C. Berry
2008-Dec-22 20:33 UTC
[R] How can I avoid nested 'for' loops or quicken the process?
On Mon, 22 Dec 2008, Brigid Mooney wrote:> Hi All, > > I'm still pretty new to using R - and I was hoping I might be able to get > some advice as to how to use 'apply' or a similar function instead of using > nested for loops.Unfortunately, you have given nothing that is reproducible. The details of MyFunction and the exact structure of the list objects are crucial. Check out the _Posting Guide_ for hints on how to formulate a question that will elecit an answer that helps you. HTH, Chuck> > Right now I have a script which uses nested for loops similar to this: > > i <- 1 > for(a in Alpha) { for (b in Beta) { for (c in Gamma) { for (d in Delta) { > for (e in Epsilon) > { > Output[i] <- MyFunction(X, Y, a, b, c, d, e) > i <- i+1 > }}}}} > > > Where Output[i] is a data frame, X and Y are data frames, and Alpha, Beta, > Gamma, Delta, and Epsilon are all lists, some of which are numeric, some > logical (TRUE/FALSE). > > Any advice on how to implement some sort of solution that might be quicker > than these nested 'for' loops would be greatly appreciated. > > Thanks! > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >Charles C. Berry (858) 534-2098 Dept of Family/Preventive Medicine E mailto:cberry at tajo.ucsd.edu UC San Diego http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901
Brigid Mooney
2008-Dec-23 14:55 UTC
[R] How can I avoid nested 'for' loops or quicken the process?
I have used some of your advice in making some changes to my function and
function call before reposting.
Instead of nesting many 'for' loops, I have gotten to the point where I
only
have one. (Also, please note, I am pasting the function calcProfit at the
end of this message as it is a bit long.)
This process works correctly, but still has a 'for' loop, which I
thought I
would be able to avoid with 'apply'.
------------------------------------------------------------------------------------------------------------------
# Sample iteration parameters (these can be vectors of arbitrary length)
# Need to iterate through all possible combinations of these parameters
Param <- list(long=c(.75, 1.5),
short=c(-.5, -1),
investment=10000,
stoploss=c(-.015),
comission=.0002,
penny=3,
volume=c(.02, .01),
numU=2,
accDefn=0:1 )
CombParam <- expand.grid(Param)
# Create sample X and Y data frames for function call
Y <- data.frame(SymbolID=10:14, OpeningPrice = c(1,3,10,20,60), ClosingPrice
= c(2,2.5,11,18,61.5), YesterdayClose= c(1,3,10,20,60), MinTrVol rep(10000000,
times=5))
X <- data.frame(SymbolID=10:14, weight = c(1, .5, -3, -.75, 2),
CPweight=c(1.5, .25, -1.75, 2, -1), noU = c(2,3,4,2,10))
for (i in 1:length(CombParam$long))
{
if(i==1)
{ Results <- calcProfit(CombParam[i,], X, Y)
} else {
Results <- rbind(Results, calcProfit(CombParam[i,], X, Y))
}
}
------------------------------------------------------------------------------------------------------------------
However, when I try to replace this for loop with 'apply', I get the
following result:
Results2 <- apply(CombParam, 1, calcProfit, X, Y)
Error in IterParam$long : $ operator is invalid for atomic vectors
Any advice that anyone could provide would be much appreciated.
Here is the function which I am using:
------------------------------------------------------------------------------------------------------------------
*calcProfit* <- function(IterParam, marketData, dailyForecast) {
long <- IterParam$long
short <- IterParam$short
investment <- IterParam$investment
stoploss <- IterParam$stoploss
comission <- IterParam$comission
penny <- IterParam$penny
volume <- IterParam$volume
numU <- IterParam$numU
accDefn <- IterParam$accDefn
compareMarket <- merge(dailyForecast, marketData,
by.x="SymbolID",
by.y="SymbolID")
weight <- ifelse(rep(accDefn, times=length(compareMarket$weight))==1,
compareMarket$weight, compareMarket$CPweight)
position <- ifelse((weight<=short & compareMarket$OpeningPrice
> penny &
compareMarket$noU>=numU), "S",
ifelse((weight>=long & compareMarket$OpeningPrice > penny &
compareMarket$noU>=numU), "L", NA))
positionTF <- ifelse(position=="L" | position=="S",
TRUE, FALSE)
estMaxInv <- volume*compareMarket$MinTrVol*compareMarket$YesterdayClose
investbySymbol <- ifelse(positionTF==TRUE, ifelse(estMaxInv
>investment, investment, 0))
opClProfit <- ifelse(position=="L",
compareMarket$ClosingPrice/compareMarket$OpeningPrice-1,
ifelse(position=="S",
1-compareMarket$ClosingPrice/compareMarket$OpeningPrice, 0.0))
Gains <- investbySymbol*ifelse(opClProfit <= stoploss, stoploss,
opClProfit)
ProfitTable <- data.frame(SymbolID=compareMarket$SymbolID,
investbySymbol, Gains, percentGains=Gains/investbySymbol,
LessComm=rep(comission, times=length(Gains)),
NetGains=Gains/investbySymbol-2*comission)
AggregatesTable <- data.frame( OutTotInvestment
sum(ProfitTable$investbySymbol, na.rm=TRUE),
OutNumInvestments = sum(ProfitTable$investbySymbol,
na.rm=TRUE)/investment, OutDolProf = sum(ProfitTable$Gains, na.rm=TRUE),
OutPerProf = sum(ProfitTable$Gains,
na.rm=TRUE)/sum(ProfitTable$investbySymbol, na.rm=TRUE),
OutNetGains = sum(ProfitTable$Gains,
na.rm=TRUE)/sum(ProfitTable$investbySymbol, na.rm=TRUE)-2*comission, OutLong
= long,
OutShort = short, OutInvestment = investment, OutStoploss stoploss,
OutComission = comission, OutPenny = penny, OutVolume = volume,
OutNumU = numU, OutAccDefn = accDefn )
return(AggregatesTable)
}
------------------------------------------------------------------------------------------------------------------
On Mon, Dec 22, 2008 at 4:32 PM, David Winsemius
<dwinsemius@comcast.net>wrote:
> I do agree with Dr Berry that your question failed on several grounds in
> adherence to the Posting Guide, so this is off list.
>
> Maybe this will give you guidance that you can apply to your next question
> to the list:
>
> > alist <- list("a","b","c")
> > blist <- list("ab","ac","ad")
>
> > expand.grid(alist, blist)
> Var1 Var2
> 1 a ab
> 2 b ab
> 3 c ab
> 4 a ac
> 5 b ac
> 6 c ac
> 7 a ad
> 8 b ad
> 9 c ad
>
> > apply( expand.grid(alist, blist), 1, function(x) paste(x[1], x[2],
> sep=""))
> [1] "aab" "bab" "cab" "aac"
"bac" "cac" "aad" "bad" "cad"
>
> > clist <- list("AA","BB")
>
> > apply(expand.grid(alist, blist, clist),1,function(x) paste(x[1], x[2],
> x[3], sep=""))
> [1] "aabAA" "babAA" "cabAA"
"aacAA" "bacAA" "cacAA" "aadAA"
"badAA"
> "cadAA" "aabBB"
> [11] "babBB" "cabBB" "aacBB"
"bacBB" "cacBB" "aadBB" "badBB"
"cadBB"
>
> > dlist <- list(TRUE,FALSE)
>
> > apply(expand.grid(alist, blist, clist, dlist),1,function(x)
paste(x[1],
> x[2], x[3], (x[4]), sep=""))[8:12]
> [1] "badAATRUE" "cadAATRUE" "aabBBTRUE"
"babBBTRUE" "cabBBTRUE"
>
>
> This could get unwieldily if the length of the lists are appreciable, since
> the number of rows will be the product of all the lengths. On the other
hand
> you could create a dataframe indexed by the variables in expand.grid's
> output:
>
> > master.df <- data.frame( expand.grid(alist, blist, clist, dlist),
> results = apply(expand.grid(alist, blist,
> clist,dlist),1,
> function(x) paste(x[1], x[2], x[3],
> (x[4]), sep="")))
>
>
>
> --
> David Winsemius
>
> On Dec 22, 2008, at 3:33 PM, Charles C. Berry wrote:
>
> On Mon, 22 Dec 2008, Brigid Mooney wrote:
>>
>> Hi All,
>>>
>>> I'm still pretty new to using R - and I was hoping I might be
able to get
>>> some advice as to how to use 'apply' or a similar function
instead of
>>> using
>>> nested for loops.
>>>
>>
>> Unfortunately, you have given nothing that is reproducible.
>>
>> The details of MyFunction and the exact structure of the list objects
are
>> crucial.
>>
>> Check out the _Posting Guide_ for hints on how to formulate a question
>> that will elecit an answer that helps you.
>>
>> HTH,
>>
>> Chuck
>>
>>
>>
>>> Right now I have a script which uses nested for loops similar to
this:
>>>
>>> i <- 1
>>> for(a in Alpha) { for (b in Beta) { for (c in Gamma) { for (d in
Delta) {
>>> for (e in Epsilon)
>>> {
>>> Output[i] <- MyFunction(X, Y, a, b, c, d, e)
>>> i <- i+1
>>> }}}}}
>>>
>>>
>>> Where Output[i] is a data frame, X and Y are data frames, and
Alpha,
>>> Beta,
>>> Gamma, Delta, and Epsilon are all lists, some of which are numeric,
some
>>> logical (TRUE/FALSE).
>>>
>>> Any advice on how to implement some sort of solution that might be
>>> quicker
>>> than these nested 'for' loops would be greatly appreciated.
>>>
>>> Thanks!
>>>
>>> [[alternative HTML version deleted]]
>>>
>>> ______________________________________________
>>> R-help@r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> PLEASE do read the posting guide
>>>
http://www.R-project.org/posting-guide.html<http://www.r-project.org/posting-guide.html>
>>> and provide commented, minimal, self-contained, reproducible code.
>>>
>>>
>> Charles C. Berry (858) 534-2098
>> Dept of Family/Preventive
>> Medicine
>> E mailto:cberry@tajo.ucsd.edu UC San Diego
>> http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego
>> 92093-0901
>>
>> ______________________________________________
>> R-help@r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide
>>
http://www.R-project.org/posting-guide.html<http://www.r-project.org/posting-guide.html>
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
>
[[alternative HTML version deleted]]