Skip to content

Avoiding a loop

7 messages · Worik R, Kenn Konstabel, Juan Carlos Borrás +3 more

#
#Use the indexes of S in a sapply function.

N <- 10
S <- sample(c(0,1), size=N, replace=TRUE)
v1 <- sapply(c(1:N-1), function(i) S[i]&&S[i+1])

# Then
v2 <- (P > m)

# And I guess you can fill up the rest. Beware of the boundary
condition (the NA in v1)

Cheers,
jcb!
_______________________
http://twitter.com/jcborras
On Fri, Apr 8, 2011 at 5:30 AM, Worik R <worikr at gmail.com> wrote:
#
2011/4/8 Juan Carlos Borr?s <jcborras at gmail.com>:
You can achieve the same v1 using

v1.2 <-  S[2:N-1] & S[2:N]

.. or if you insist on having NA as the first element, -- c(NA, v1.2)

Vectorization is more efficient than loops but this need not be true
for the *apply functions.
#
Kenn,
I find your solution more elegant.

2011/4/8 Kenn Konstabel <lebatsnok at gmail.com>:
#
Hi,

this response uses the previous responses with an example:

#Assume you have 100 observations
n=100

#Simulate a time series of prices
error=rnorm(n,0,3)
raw.price=rpois(n,100)
lag.price=c(rpois(1,100),raw.price[1:99])
price=lag.price+error

#Say you want the moving average based on this
#and the four preceding prices
#define the moving average lag
MA.lag=4

#Create an index vector from MA.lag+1
#(the first time for which you can compute the MA)
#until the end
index=matrix((MA.lag+1):n)

#Define a function that computes the moving average
#by taking the mean over the observations
#from (x-MA.lag) to x
MA=function(x){mean(price[(x-MA.lag):x])}

#apply this function over all rows of the 'index' matrix
#which yields the moving averages
mov.av=apply(index,1,MA)

#Now apply the previous solutions
#First, create a T/F vector whether the price is greater 
#than the moving average
S=price[(MA.lag+1):n]>mov.av

#Now create an indicator whether the relation between
#price and moving average changes
v1 <- sapply(2:(n-MA.lag),function(i)S[i]!=S[i-1])

#Output a data frame; when True, column 'signal'
#indicates that the system recommends a transaction
data=data.frame(price[(MA.lag+2):n],mov.av[-1],S[-1],v1)
names(data)=c('price','moving.average','price.greater.ma','signal')
data

HTH,
Daniel

--
View this message in context: http://r.789695.n4.nabble.com/Avoiding-a-loop-tp3435070p3435559.html
Sent from the R help mailing list archive at Nabble.com.
#
Use 'diff' to determine where the changes are:
[1] 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 1 0
[1]  4  9 13 15 18 21 23 29
then use the indices for the other processing.
On Thu, Apr 7, 2011 at 10:30 PM, Worik R <worikr at gmail.com> wrote:

  
    
#
I believe the solutions proposed ignore the recursive nature of the
original problem and hence produce wrong solutions.

P <- c(5, 7, 6.01, 6.01, 7)
m <- rep(6, 5)
S0 <- as.numeric(P>(m*1.005))

Then the original loop from Worik gives

S <- S0
for(i in 2:length(S)){
   if(S[i]==0 && S[i-1] == 1){
     if(P[i] > m[i]){
       S[i] <- 1
     }
   }
}

 > S
[1] 0 1 1 1 1

The other solutions I have seen on the list suggest looking
upfront on differences in S, and I am pretty sure the intentions
were to produce

S <- S0
v <- c(FALSE, (S[-1] == 0) & (S[-5] == 1)) & (P > m)

where v equals c(FALSE, FALSE, TRUE, FALSE, FALSE) and then

S[v] <- 1

giving

 > S
[1] 0 1 1 0 1

When you recursively update a vector like this I don't know any
general vectorization fix.

- Niels
On 08/04/11 00.58, Juan Carlos Borr?s wrote: