Search code examples
rdataframefor-loopeconomics

Error in creating function for elasticity for demand schedule in R


Trying to create a function that takes in a demand schedule and adds a column in the data frame that has elasticity at each point. If you run my code below, you get a data frame with repeated values in each column. Is there something wrong with my for loop?

elasticity <- function(df){
  df$PCP <- NULL #percentage change in price 
  df$PCQ <- NULL #percentage change in quantity
  df$elasticity<- NULL #elasticity
  for (i in 1:length(df$Price)){
    df$PCP[i] <- 100*(df$Price[i]-df$Price[i+1])/(0.5*(df$Price[i]+df$Price[i+1])) 
  df$PCQ[i] <- 100*(df$Quantity[i+1]-df$Quantity[i])/(0.5*(df$Quantity[i]+df$Quantity[i+1]))
  df$elasticity[i] <- df$PCQ[i]/df$PCP[i]
  return(df)
  }
}
df <- data.frame("Price"=c(7:0), "Quantity"=seq(0,14, by=2))
elasticity(df)

Solution

  • You need to put your return statement outside of your loop.

    I think placing return inside your loop is exiting the function entirely, which is why the first result is being generated. From datamentor.io, "If it is not the last statement of the function, it will prematurely end the function bringing the control to the place from which it was called."

    sample_function <- function(){
      print("Hi!")
      for(i in seq_along(rep(1,6))){
        return(i)
        print("This is not evaluated")
      }
      print("This is not evaluated either")
    }
    sample_function()
    
    > sample_function()
    [1] "Hi!"
    [1] 1
    

    Also, since you're doing i +/- i + 1 be mindful of "off-by-one".

    elasticity <- function(df){
      df$PCP <- NULL #percentage change in price 
      df$PCQ <- NULL #percentage change in quantity
      df$elasticity<- NULL #elasticity
      for (i in seq_along(df$Price)){
        df$PCP[i] <- 100*(df$Price[i]-df$Price[i+1])/(0.5*(df$Price[i]+df$Price[i+1])) 
        df$PCQ[i] <- 100*(df$Quantity[i+1]-df$Quantity[i])/(0.5*(df$Quantity[i]+df$Quantity[i+1]))
        df$elasticity[i] <- df$PCQ[i]/df$PCP[i]
        df
      }
      return(df)
    }
    
    > elasticity(df)
      Price Quantity       PCP       PCQ  elasticity
    1     7        0  15.38462 200.00000 13.00000000
    2     6        2  18.18182  66.66667  3.66666667
    3     5        4  22.22222  40.00000  1.80000000
    4     4        6  28.57143  28.57143  1.00000000
    5     3        8  40.00000  22.22222  0.55555556
    6     2       10  66.66667  18.18182  0.27272727
    7     1       12 200.00000  15.38462  0.07692308
    8     0       14        NA        NA          NA