Search code examples
rdataframematrixapplylinear-equation

R: Automate solving many systems of equations in data frame


I'm working on a dataset that will solve simple equation systems of 2 equations with 2 unknowns. However, as there are hundreds of such systems, I will need to find some algorithm, perhaps a loop, that will perform the task for n rows in a data frame.

Consider the following data frame:

df <- as.data.frame(rbind(c(1,  0.214527122,    166486.7605,    1,  -0.003217907,   0),
            c(1,    0.227828903,    160088.1385,    1,  -0.003417434,   0),
            c(1,    0.214324606,    154445.4132,    1,  -0.003214869,   0),
            c(1,    0.218698883,    147921.278,     1,  -0.003280483,   0),
            c(1,    0.201444364,    151268.6711,    1,  -0.003021665,   0)))
colnames(df) = c("y1",  "x1",   "b1",   "y2",   "x2",   "b2")

Notice how each row in this data set contains two linear equations, for two unknowns, x and y.

> df
  y1        x1       b1 y2           x2 b2
1  1 0.2145271 166486.8  1 -0.003217907  0
2  1 0.2278289 160088.1  1 -0.003417434  0
3  1 0.2143246 154445.4  1 -0.003214869  0
4  1 0.2186989 147921.3  1 -0.003280483  0
5  1 0.2014444 151268.7  1 -0.003021665  0

The two equations represent supply and demand curves in an economic model. I want to calculate the resulting equilibrium price and quantity for each row in the data frame.

I can, for example, solve the first row with the following code:

A <- rbind(c(df$y1[1], df$x1[1]), 
           c(df$y2[1], df$x2[1]))

B <- c(df$b1[1],df$b2[1])

> solve(A,B)
[1]   2460.396 764595.000

At equilibrium, price is 2460.4 and quantity is 764 595. I can then add this result to the data frame in two new columns:

df$Price[1] <- solve(A,B)[1]
df$Quantity[1] <- solve(A,B)[2]

> df
  y1        x1       b1 y2           x2 b2    Price Quantity
1  1 0.2145271 166486.8  1 -0.003217907  0 2460.396   764595
2  1 0.2278289 160088.1  1 -0.003417434  0       NA       NA
3  1 0.2143246 154445.4  1 -0.003214869  0       NA       NA
4  1 0.2186989 147921.3  1 -0.003280483  0       NA       NA
5  1 0.2014444 151268.7  1 -0.003021665  0       NA       NA

That was the first row. But I haven't figured out a good way of automating this to solve for each row in the data frame. I suppose some type of loop might be an option, but I've had no luck in solving it.


Solution

  • Rearrange the columns so that the first 4 are the matrix and then run the following apply :

    df2 <- df[c("y1", "y2", "x1", "x2", "b1", "b2")]
    t(apply(df2, 1, function(x) solve(matrix(x[1:4], 2), x[5:6])))
    

    giving

             [,1]   [,2]
    [1,] 2460.396 764595
    [2,] 2365.835 692284
    [3,] 2282.444 709965
    [4,] 2186.029 666374
    [5,] 2235.497 739823