library(cjEuclid)

1 Functions

The package has three functions and a wrapper.

1.1 lm_euclid

lm_euclid fits a model with interactions and quadratic terms given a formula. It seeks to return the parameters of a generalized Euclidean model of the form:

For instance:

r <- matrix(c(1, .15, .15, 2), 2, 2)
p <- c(.1, .5)

u <- function(butter = 0, guns = 0)
  -(c(butter, guns) - p) %*% r %*% (c(butter, guns) -p)


data <-
 fabricatr::fabricate(N = 100,
                      butter = rnorm(N), 
                      guns = rnorm(N))
data$rating <- sapply(1:nrow(data), function(i) u(data$butter[i], data$guns[i]))



euclid <-  lm_euclid(rating ~ guns + butter, data)

euclid
## 
##  ------------------------------------------------------------------------------------------
## 
##  Coefficients: 
## (Intercept)        guns      butter   I(guns^2) I(butter^2) guns:butter 
##      -0.525       2.030       0.350      -2.000      -1.000      -0.300 
## 
##  ------------------------------------------------------------------------------------------
## 
##  Matrix is positive semi definite: 
## 
##  The implied A matrix: 
##        guns butter
## guns   2.00   0.15
## butter 0.15   1.00
## 
##  Eigenvalues: 
## [1] 2.0220153 0.9779847
## 
##  Ideals: 
##      guns butter
## [1,]  0.5    0.1

The function simply creates the Euclidian formula and passes it to fixest.

You can provide any additional fixest functions you want as additional arguments.

1.2 euclid_fits

euclid_fits is a simple helper to generate fitted values for a model given specified ranges and length

predictions_df <- 
  euclid_fits(formula = rating ~ guns + butter, euclid$model, data, lengths = c(2,3))

predictions_df |> kable(digits = 3)
guns butter utility
-3.307 -2.710 -40.085
-3.307 -0.190 -29.397
-3.307 2.329 -31.404
2.369 -2.710 -13.307
2.369 -0.190 -6.909
2.369 2.329 -13.206

1.3 euclid_plot

euclid_plot call ggplot to plot the predicted fits and adds ideal points

predictions_df <- 
  euclid_fits(formula = rating ~ guns + butter, euclid$model, data, lengths = c(20,20))

euclid_plot(predictions_df, X = "guns", Y = "butter")

1.4 cj_euclid

cj_euclid wraps these functions and returns a list with the model, the fitted values, and the graph.

euclid <- cj_euclid(rating ~ guns + butter, data)
euclid$graph

2 Examples

The functions include multiple arguments to allow graphing multiple dimensions. Here we illustrate plotting 2 dimensions with faceting by a third.

# Data has three dimensions and two observations per subject

library(fabricatr)

data <-
 fabricate(
   ID = add_level(20),
   choice = add_level(2,
                      A = rnorm(N), B = rnorm(N), C = rnorm(N),
                      W = -(A^2 + (B-.3)^2 + (C --.67)^2) + .2*rnorm(N) + .5*A*B))


results <- 
  cj_euclid(W ~ A + B + C,
           fixed_effects = "ID",
           data = data,
           X = "B",
           Y = "C",
           Col = "A",
           mins = c(-2, -2, -2),
           maxs = c(2, 2, 2),
           lengths = c(5, 25, 35),
           y_vals = c("little", "some", "much"),
           x_vals = c("This", "that", "there"))

results$model
## OLS estimation, Dep. Var.: W
## Observations: 40 
## Fixed-effects: ID: 20
## Standard-errors: Heteroskedasticity-robust 
##         Estimate Std. Error    t value   Pr(>|t|)    
## A       0.048719   0.098343   0.495400 6.3007e-01    
## B       0.631668   0.035835  17.627189 2.0621e-09 ***
## C      -1.358839   0.039284 -34.589827 1.4140e-12 ***
## I(A^2) -1.012499   0.045846 -22.084989 1.8399e-10 ***
## I(B^2) -1.005708   0.023713 -42.411311 1.5251e-13 ***
## I(C^2) -1.003185   0.044589 -22.498509 1.5064e-10 ***
## A:B     0.471228   0.072986   6.456388 4.7007e-05 ***
## A:C    -0.035085   0.020554  -1.706985 1.1586e-01    
## B:C    -0.048768   0.066364  -0.734855 4.7780e-01    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## RMSE: 0.090181     Adj. R2: 0.997924
##                  Within R2: 0.998917
results$graph

more ggplotting can be done later:

results$graph + 
  ylab("another label and a flip") + coord_flip() 
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.

2.1 4 d

# Data has three dimensions and two observations per subject

data <-
 fabricate(
   ID = add_level(20),
   choice = add_level(2,
                      X1 = rnorm(N), X2 = rnorm(N), X3 = rnorm(N), X4 = rnorm(N), 
                      W = -(X1^2 + (X2-.3)^2 + (X3 --.67)^2 + X4^2)  + .2*rnorm(N)))


results <- 
  cj_euclid(W ~ X1 + X2 + X3 + X4,
           fixed_effects = "ID",
           data = data,
           X = "X1",
           Y = "X2",
           Row = "X3",
           Col = "X4",
           mins = c(-2, -1, -2, -2),
           maxs = c(2, 1, 2, 2),
           lengths = c(35, 25, 5, 3),
           y_vals = c("little", "some", "much"),
           x_vals = c("This", "that", "there"))

results$graph

2.2 Subgroup plots

Can be done by treating a subgroup as a variable, by stitching multiple plots together, or by running lm_euclid adn cj_Euclid on multiple groups and then applying the plot function with the group as a dimension.

2.3 Example when \(A\) is not positive semi definite

data <-
 fabricatr::fabricate(N = 40,
                      butter = rnorm(N), 
                      guns = rnorm(N),
                      rating  = -(butter^2 - (guns-.3)^2 + .2*rnorm(N)))

euclid <- cj_euclid(rating ~ guns + butter, data)
## Warning in lm_euclid(formula, data, fixed_effects = fixed_effects, ...): The
## estimated A matrix is not positive semi definite
euclid
## 
##  ------------------------------------------------------------------------------------------
## 
##  Coefficients: 
## (Intercept)        guns      butter   I(guns^2) I(butter^2) guns:butter 
##  0.05530852 -0.58598394 -0.04890019  0.98939555 -0.99236155 -0.01924133 
## 
##  ------------------------------------------------------------------------------------------
## 
##  Matrix is not positive semi definite: 
## 
## A matrix: 
##                guns      butter
## guns   -0.989395551 0.009620667
## butter  0.009620667 0.992361554
## 
## A Eigenvalues: 
## [1]  0.9924083 -0.9894423
## 
##  Ideals not calculated (edge solution)
euclid$graph