Search code examples
rzoo

R - using merge.zoo with a custom column name


I am using a for loop to iterate through a list of fund codes, make an API call and then combine this data in one large zoo object. I would like to see something like this (shortened version), where there is a simple change between each column (Zoo1, Zoo2, Zoo3):

Wanted results

However currently I have column headers like this:

Current results

I have researched into ways to do this (for example if there was a parameter of merge.zoo for a custom name) however I can't seem to find anything.

Currently my code is looking like this:

## Imported libraries
library(httr)     ## Library to make the HTTP get request
library(jsonlite) ## Library to de-code the JSON
library(lattice)  ## Help with the output plots
library(zoo)      ## Use with data frames
library(ggplot2)  ## Used for plotting

## Percentage Change - calculates the percentage difference from the first value to all of the next values, in a dataframe
PercentageChange <- function(dataframe) {
  Values <- as.vector(dataframe$navPrice)   ## Collect the navPrice as a vector 
  ReturnValues <- c()   ## Create a vector for the values that we are going to return
  StartValue <- Values[length(Values)]    ## Find the start value that we can base all of the data on
  for (Value in Values) {   ## Loop through all of the price values.
    PercentageChangeValue <- (Value-StartValue)/StartValue*100    ## Calculate the percentage change difference between the current and start value using the percentage change formula
    ReturnValues <- append(ReturnValues, PercentageChangeValue)   ## Add that value to the values that we will return
  }
  return(ReturnValues)    ## Return the vector that we created
}

## Call API - based on the fund code given to us, collect the data from the AI, for a certain date range
CallAPI <- function(Fund, Start="1950-01-01", End="2050-01-01") {
  Data <- read.csv("Data/VanguardFundApiNumbers.csv")   ## Collect the data from the CSV file with the API Lookup codes and put that into a dataframe
  Code <- Data[Data$Ticker == Fund, ]$VanguardCode    ## Look up the row with the fund code and then take the ticker code for the API
  Res <- GET(paste("https://www.vanguardinvestor.co.uk/api/fund-data/", Code, "/S/price-history?startDate=", Start, "&endDate=", End, sep=""))    ## Create the URL that we will send a request to, and then send it
  FundData <- fromJSON(rawToChar(Res$content))    ## Turn the raw data into a string, and then into JSON which can be assigned into the return variable
  return(FundData)    ## Return the return data
}

## Create Just Date Values - returns a list of date times without the time in a more readable format
CreateJustDateValues <- function(Dates) {
  ReturnList <- c()   ## Create a list for the return values
  for (Date in Dates) {   ## Loop through the dates
    ReturnList <- append(ReturnList, gsub("-", ".", substr(Date, 1, 10)))   ## For each date, take the first ten chars, replace any dashes with . and then add that to the return list
  }
  return(ReturnList)    ## Return the list we have created
}

## Create a list of the funds that we want to look at
Funds <- c("VDEE", "VDWE", "VGAC", "VGSC", "VUSE", "VJSI", "VLSH")
StartDate <- "2021-06-01"
EndDate <- "2050-01-01"
## Creates the first fund for testing and to help set up the variable
FundData <- CallAPI(Funds[1], Start=StartDate)
FundData$percentChange <- PercentageChange(FundData)
Combination <- zoo(FundData$percentChange, FundData$date)

## Loops through the remaining funds
for (Fund in Funds[2:length(Funds)]) {
  FundData <- CallAPI(Fund, Start=StartDate)                ## Returns a DataFrame with the data
  FundData$percentChange <- PercentageChange(FundData)      ## Create a percentage change column that we can analyse
  ZooObject <- zoo(FundData$percentChange, FundData$date)   ## Turn the wanted data into a zoo object
  Combination <- merge.zoo(Combination, ZooObject)          ## Combine it to the previous objects
}

Any explanation to how I could improve the column headers would be great!


Solution

  • If the problem is to merge zoo vector z0 onto zoo object z such that the new column has name "X" then make z0 into a column vector zoo object and use setNames :

    library(zoo)
    
    z <- read.zoo(BOD)
    z0 <- 10*z
    
    merge(z, setNames(cbind(z0), "X"))
    

    giving:

         z   X
    1  8.3  83
    2 10.3 103
    3 19.0 190
    4 16.0 160
    5 15.6 156
    7 19.8 198
    

    If hard coding X is ok then it can be written:

    merge(z, X = z0)