Andrew Bannerman
Andrew Bannerman

Reputation: 1305

R - More elegant way of writing line of code

Ok so lets take this code below which calculates a rolling simple moving average over 2 day period:

# Use TTR package to create rolling SMA n day moving average 
new.df$close.sma.n2 <- SMA(new.df[,"Close"], 2)

Lets say I want to calculate the n day period of 2:30

The inputs here is:

close.sma.n** and also the numerical value for the SMA calculation.

So my question is: How can I write one line of code to perform the above calculation on different SMA periods and also making a new column with corresponding close.sma.n2,3,4,5,6 etc value in a data frame?

I understand I can do:

n.sma <- 2:30

and put that variable in:

new.df$close.sma.n2 <- SMA(new.df[,"Close"], n.sma)

Perhaps I can:

name <- "n2:30"

and place that inside:

 new.df$close.sma.name <- SMA(new.df[,"Close"], n.sma)

Upvotes: 0

Views: 58

Answers (1)

Julian Zucker
Julian Zucker

Reputation: 564

You didn't provide sample data or SMA, so I made up dummy functions to test my code.

df <- data.frame(Close=c(1, 2, 3, 4))
SMA <- function(x, numdays) {numdays}

Then, I wrote a function that takes in the number of days to average, and returns a function that takes a data.frame and takes the SMA over that many days.

getSMA <- function(numdays) {
  function(new.df) {
    SMA(new.df[,"Close"], numdays)
  }
}

Then, create a matrix to put the SMAs in

smas <- matrix(nrow=nrow(df), ncol=0)

and fill it.

for (i in 2:30) {
  smas <- cbind(smas, getSMA(i)(df))
}

Then, set the column names to what you want them to be

colnames(smas) <- sapply(2:30, function(n)paste("close.sma.n", n, sep=""))

and bind it with the starting data frame.

df <-  cbind(df, smas)

Now you have your original data.frame, plus "close.sma.n2" through ".n30"

Upvotes: 2

Related Questions