library(cjEuclid)
The package has three functions and a wrapper.
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.
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 |
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")
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
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 ggplot
ting 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.
# 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
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.
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