[R] How can I avoid nested 'for' loops or quicken the process?

David Winsemius dwinsemius at comcast.net
Tue Dec 23 20:01:38 CET 2008


I have to agree with Daniel Nordlund regarding not creating subsidiary  
problems when the main problem has been cracked. Nonetheless, ...   
might you be happier with the result of changing the last data.frame()  
call in calcProfit to c()?

I get a matrix:
 > str(Results2)
  num [1:14, 1:16] 3.00e+04 3.00 -4.50e+02 -1.50e-02 -1.54e-02  
7.50e-01 -5.00e-01 1.00e+04 -1.50e-02 2.00e-04 ...
  - attr(*, "dimnames")=List of 2
   ..$ : chr [1:14] "OutTotInvestment" "OutNumInvestments.investment"  
"OutDolProf" "OutPerProf" ...
   ..$ : NULL

... if you go along with that strategy, then I think it is possible  
that you really want as.data.frame( t( Results2)) since the rows and  
columns seem to be transposed from what I would have wanted.

Now, ...  your next task is to set up your mail-client so it sends  
unformatted text to R-help.

-- 
David Winsemius
Heritage Labs

On Dec 23, 2008, at 11:36 AM, Brigid Mooney wrote:

> ------------------------------------------------------------------------------------------------------------------------------
> Problem Description:  (reproducible code below)
> ------------------------------------------------------------------------------------------------------------------------------
> I cannot seem to get as.data.frame() to work as I would expect.
>
>  Results2 seems to contain repeated column titles for each row, as  
> well as a row name 'investment' (which is not intended), like:
>  Results2
> [[1]]
>            OutTotInvestment OutNumInvestments OutDolProf OutPerProf  
> OutNetGains OutLong OutShort OutInvestment OutStoploss OutComission  
> OutPenny OutVolume OutNumU OutAccDefn
> investment            30000                 3       -450      
> -0.015     -0.0154    0.75     -0.5         10000      -0.015         
> 2e-04        3      0.02       2          0
> [[2]]
>            OutTotInvestment OutNumInvestments OutDolProf OutPerProf  
> OutNetGains OutLong OutShort OutInvestment OutStoploss OutComission  
> OutPenny OutVolume OutNumU OutAccDefn
> investment            30000                 3       -450      
> -0.015     -0.0154     1.5     -0.5         10000      -0.015         
> 2e-04        3      0.02       2          0
> ...
>
> When I try to apply 'as.data.frame', it concatenates incremental  
> numbers to the repeated row headers and gives:
> as.data.frame(Results2)
>            OutTotInvestment OutNumInvestments OutDolProf OutPerProf  
> OutNetGains OutLong OutShort OutInvestment OutStoploss OutComission  
> OutPenny OutVolume OutNumU OutAccDefn
> investment            30000                 3       -450      
> -0.015     -0.0154    0.75     -0.5         10000      -0.015         
> 2e-04        3      0.02       2          0
>            OutTotInvestment.1 OutNumInvestments.1 OutDolProf.1  
> OutPerProf.1 OutNetGains.1 OutLong.1 OutShort.1 OutInvestment.1  
> OutStoploss.1 OutComission.1 OutPenny.1
> investment              30000                   3         -450        
> -0.015       -0.0154       1.5       -0.5           10000         
> -0.015          2e-04          3
>            OutVolume.1 OutNumU.1 OutAccDefn.1 OutTotInvestment.2  
> OutNumInvestments.2 OutDolProf.2 OutPerProf.2 OutNetGains.2 OutLong. 
> 2 OutShort.2 OutInvestment.2
> investment        0.02         2            0               
> 30000                   3         -450       -0.015        
> -0.0154      0.75         -1           10000
> ...
>
> which is a data frame of dimension 1 224, when I am looking for a  
> data frame like Results of dimension 16 14.
>
>
> ------------------------------------------------------------------------------------------------------------------------------
> Reproducible code:
> ------------------------------------------------------------------------------------------------------------------------------
> # --------------------------------------------------------------
> # FUNCTION calcProfit
> # --------------------------------------------------------------
> calcProfit <- function(IterParam,  marketData, dailyForecast) #,  
> long, short, investment, stoploss, comission, penny, volume, numU,  
> accDefn)
>   {
>     if (class(IterParam) == "numeric")
>       {
>         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"]
>       } else {
>           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)
>   }
>
>
> # 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))
>        }
>   }
>
>
> Results2 <- apply(CombParam, 1, calcProfit, X, Y)
>
> ------------------------------------------------------------------------------------------------------------------------------
>
>
> On Tue, Dec 23, 2008 at 11:15 AM, David Winsemius <dwinsemius at comcast.net 
> > wrote:
>
> On Dec 23, 2008, at 10:56 AM, Brigid Mooney wrote:
>
> Thank you again for your help.
>
> snip
>
>
>
> -------------
> With the 'apply' call, Results2 is of class list.
>
> Results2 <- apply(CombParam, 1, calcProfit, X, Y)
> -------------------------------------------------------------------------------------------------------
>
> How can I get convert Results2 from a list to a data frame like  
> Results?
>
> Have you tried as.data.frame() on Results2? Each of its elements  
> should have the proper structure.
>
> You no longer have a reproducible example, but see this session clip:
> > lairq <- apply(airquality,1, function(x) x )
> > str(lairq)
>  num [1:6, 1:153] 41 190 7.4 67 5 1 36 118 8 72 ...
>  - attr(*, "dimnames")=List of 2
>  ..$ : chr [1:6] "Ozone" "Solar.R" "Wind" "Temp" ...
>  ..$ : NULL
> > is.data.frame(lairq)
> [1] FALSE
> > is.data.frame(rbind(lairq))
> [1] FALSE
> > is.data.frame( as.data.frame(lairq) )
> -- 
> David Winsemius
>



More information about the R-help mailing list