# load packages 
suppressMessages(library(Zillow))
suppressMessages(library(rvest))
suppressMessages(library(dplyr))
suppressMessages(library(DT))

# create example data frame of addresses 
data <- data.frame(  
          street = c('2925 SW 4th Ave', 
                     '2615 SE 75th Ave', 
                     '7245 N Newell Ave', 
                     '4305 SE Ash St',
                     '7052 N Wilbur Ave', 
                     '7708 SE Springwater Dr',
                     'Test Not an Address'),
          city.state=c(rep('Portland, OR', 7)))



# To run this function you must create an account at zillow.com 
# Then create an api key for your account and paste it in line 48 

# create get.zestimate function 
  # get zestimate function takes a dataframe with two required columns and returns that data frame with cbound zestimate data
  # 1) street: is the street address of the homes
  # 2) city.state: is either the city, state (e.g., Portland, OR) or the zipcode of the homes 
  
get.zestimate <- function(df, street, city.state){

  # require Zillow package (install.packages("Zillow", repos="http://www.omegahat.org/R", type="source", dependencies="Depends"))
  require(Zillow)
  
  # define zillow api id 
  #zillowId <- 'XXXXX'  ### enter your zillow api id here ###
  
  # apply zestimate function to each row of a data frame and rbind the results using tryCatch 
  results <-  do.call(rbind, lapply(1:nrow(df), function(i){
  # fetch zestimate data from zillow 
  z <-  tryCatch({  
   zestimate <- zestimate(address=df$street[i], citystatezip=data$city.state[i], zillowId=zillowId)
  # zestimate data to be rbound into results df 
  return(zestimate)
  },
  
  error = function(cond) {
    message(paste("No Zestimate Available:", df$street[i], df$city.state[i]))
    return(NA) # Choose a return value in case of error
  },
  
  warning = function(cond) {
    message(paste("Zestimate caused a warning:", df$street[i], df$city.state[i]))
    return(NA) # Choose a return value in case of warning
  },
  # print processing message to screen
  finally = {
    message(paste("Processed Address:", df$street[i], df$city.state[i]))
    message(paste(i, "of", nrow(df), 'processed'))
  }
  )
  }))
  # rbind zestimate results with addresses 
  # return a data frame called results with nrow(df) and zestimate data in columns 
  if(nrow(results)==nrow(df)) {
    results <- cbind(df, results)
      # print summary of function results
      print(paste('Original data had', nrow(df), 'rows. Returning a dataframe with', nrow(results), 
              'rows. Returned data frame has', sum(is.na(results$amount)), 'missing Zestimate values.'))  
    
    return(results)
    }
  else(print("Error: Nrows(df) do not match nrows(zestimate)"))
}



# run function on example data 
example <- get.zestimate(data)
## Processed Address: 2925 SW 4th Ave Portland, OR
## 1 of 7 processed
## Processed Address: 2615 SE 75th Ave Portland, OR
## 2 of 7 processed
## Processed Address: 7245 N Newell Ave Portland, OR
## 3 of 7 processed
## Processed Address: 4305 SE Ash St Portland, OR
## 4 of 7 processed
## Processed Address: 7052 N Wilbur Ave Portland, OR
## 5 of 7 processed
## Processed Address: 7708 SE Springwater Dr Portland, OR
## 6 of 7 processed
## No Zestimate Available: Test Not an Address Portland, OR
## Processed Address: Test Not an Address Portland, OR
## 7 of 7 processed
## [1] "Original data had 7 rows. Returning a dataframe with 7 rows. Returned data frame has 1 missing Zestimate values."
datatable(example, rownames=FALSE, extensions = 'ColReorder', 
          options = list(dom = 'Rrti'), 
          caption = "Zestimate Data for Addresses in Example Data")%>%
    formatCurrency(c('amount', 'low', 'high', 'valueChange30Day'))