Reputation: 23607
I have let say a xts object (data) with following values...
SPY.Adjusted SMA
2012-08-02 136.64 137.115
2012-08-03 139.35 137.995
2012-08-06 139.62 139.485
2012-08-07 140.32 139.970
2012-08-08 140.49 140.405
2012-08-09 140.61 140.550
2012-08-10 140.84 140.725
I'm trying to use apply function to append to it the signals if some conditions are met... in this case when the close > SMA. My function:
signal<-function(x,y,z)
{
z$signals<-ifelse(x>y,1,0)
}
and I try to...
apply(data,1,FUN=signal(data$SPY.Adjusted,data$SMA,data))
with returned error:
Error in match.fun(FUN) : 'signal(data$SPY.Adjusted, data$SMA, data)'
is not a function, character or symbol
What is possibly going wrong? I passed in to it a function which reaches in to the data objected passed into it to create a new column if certain condition is met.
Upvotes: 2
Views: 3470
Reputation: 193687
@GSee's answer addresses your actual question, but I find this to be much more direct:
dat$signal = (dat[,1] > dat[,2]) + 0
The part (dat[,1] > dat[,2])
creates a vector of TRUE
and FALSE
, which, when you add "0" to it, converts it to 0 for FALSE
and 1 for TRUE
.
(dat
, in this example, is the same as @GSee's dat
.)
Of course, you can use this to also match more than one condition:
set.seed(1)
dat$SAMPLE = sample(as.vector(c(dat$SPY.Adjusted, dat$SMA)), nrow(dat))
dat$signal = (dat$SPY.Adjusted > dat$SMA & dat$SPY.Adjusted > dat$SAMPLE) + 0
tail(dat, 15)
# SPY.Adjusted SMA SAMPLE signal
# 2011-12-09 124.07 122.421 125.990 0
# 2011-12-12 122.26 122.864 124.260 0
# 2011-12-13 121.11 123.159 128.350 0
# 2011-12-14 119.82 122.839 114.966 0
# 2011-12-15 120.26 122.565 128.490 0
# 2011-12-16 120.44 122.320 126.486 0
# 2011-12-19 119.15 121.812 128.598 0
# 2011-12-20 122.75 121.660 127.605 0
# 2011-12-21 122.99 121.485 119.150 1
# 2011-12-22 124.08 121.693 116.030 1
# 2011-12-23 125.19 121.805 104.870 1
# 2011-12-27 125.29 122.108 116.460 1
# 2011-12-28 123.64 122.361 126.127 0
# 2011-12-29 124.92 122.871 119.750 1
# 2011-12-30 124.31 123.276 104.110 1
Upvotes: 2
Reputation: 49830
When you call apply with MARGIN=1
, it's like passing each row to FUN
. Your function is already vectorized, so you don't need to use apply
. However, your function does not return anything. Try this:
library(quantmod)
getSymbols("SPY", src='yahoo', from='2010-01-01', to='2012-01-01')
dat <- cbind(Ad(SPY), SMA=SMA(Ad(SPY)))
signal<-function(x,y,z)
{
z$signals<-ifelse(x>y,1,0)
z
}
tail(signal(dat[, 1], dat[, 2], dat))
# SPY.Adjusted SMA signals
#2011-12-22 124.08 121.693 1
#2011-12-23 125.19 121.805 1
#2011-12-27 125.29 122.108 1
#2011-12-28 123.64 122.361 1
#2011-12-29 124.92 122.871 1
#2011-12-30 124.31 123.276 1
Actually, I try to avoid ifelse
in situations like these because it is slower than doing this
signal<-function(x,y,z)
{
z$signals <- 0
z$signals[x > y] <- 1
z
}
Upvotes: 4