Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
Package: lfe
Version: 2.9-1
Date: 2023-04-03
Version: 3.0-0
Title: Linear Group Fixed Effects
Authors@R: c(person("Simen", "Gaure", email="Simen.Gaure@frisch.uio.no", role=c("aut"),
comment=c(ORCID="https://orcid.org/0000-0001-7251-8747")),
person("Grant","McDermott", email="grantmcd@uoregon.edu", role="ctb"),
person(given = "Mauricio",
family = "Vargas",
role = "ctb",
email = "mavargas11@uc.cl",
comment = c(ORCID = "0000-0003-1017-7574")),
person(given = "Paulo",
family = "Alcazar",
role = "ctb"),
person("Karl", "Dunkle Werner", role="ctb"),
person("Matthieu","Stigler", email = "Matthieu.Stigler@gmail.com", role= c("ctb", "cre"),
comment =c(ORCID="0000-0002-6802-4290")),
person("Daniel","Lüdecke",email="mail@danielluedecke.de",role="ctb"))
Copyright: 2011-2019, Simen Gaure
Authors@R: c(
person(given = "Simen",
family = "Gaure",
role = "aut",
comment = c(ORCID="https://orcid.org/0000-0001-7251-8747")),
person(given = "Grant",
family = "McDermott",
role = "ctb"),
person(given = "Mauricio",
family = "Vargas Sepulveda",
role = c("ctb", "cre"),
email = "m.sepulveda@mail.utoronto.ca",
comment = c(ORCID = "0000-0003-1017-7574")),
person(given = "Karl",
family = "Dunkle Werner",
role ="ctb"),
person(given = "Matthieu",
family = "Stigler",
role = "ctb",
comment = c(ORCID="0000-0002-6802-4290")),
person(given = "Daniel",
family = "Lüdecke",
role ="ctb"))
Depends: R (>= 2.15.2), Matrix (>= 1.1-2)
Imports: Formula, xtable, compiler, utils, methods, sandwich, parallel
Suggests:
Expand All @@ -36,13 +42,13 @@ Description: Transforms away factors with many levels prior to doing an OLS.
Useful for estimating linear models with multiple group fixed effects, and for
estimating linear models which uses factors with many levels as pure control variables. See Gaure (2013) <doi:10.1016/j.csda.2013.03.024>
Includes support for instrumental variables, conditional F statistics for weak instruments,
robust and multi-way clustered standard errors, as well as limited mobility bias correction (Gaure 2014 <doi:10.1002/sta4.68>).
WARNING: This package is NOT under active development anymore, no further improvements are to be expected, and the package is at risk of being removed from CRAN.
License: Artistic-2.0
robust and multi-way clustered standard errors, as well as limited mobility bias correction (Gaure 2014 <doi:10.1002/sta4.68>).
Since version 3.0, it provides dedicated functions to estimate Poisson models.
License: MIT + file LICENSE
Classification/JEL: C13, C23, C60
Classification/MSC: 62J05, 65F10, 65F50
URL: https://github.com/MatthieuStigler/lfe
BugReports: https://github.com/MatthieuStigler/lfe/issues
URL: https://github.com/r-econometrics/lfe
BugReports: https://github.com/r-econometrics/lfe/issues
Encoding: UTF-8
RoxygenNote: 7.2.3
Roxygen: list(markdown = TRUE)
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
YEAR: 2023
COPYRIGHT HOLDER: lfe authors
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# MIT License

Copyright (c) 2023 lfe authors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
11 changes: 11 additions & 0 deletions R/feglm.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#' @param cluster optional variable to group by and compute sandwich-type
#' robust standard errors. Should be a formula of the form `~x_j` or
#' an object that be coerced to a formula.
#' @param pseudo_rsq logical value to return a a pseudo-R2 based on Kendall's
#' correlation.
#' @param tol tolerance value for GLM convergence criteria.
#' @importFrom Formula Formula
#' @importFrom Matrix Diagonal
Expand All @@ -21,6 +23,7 @@ fepois <- function(formula, data,
subset = NULL,
robust = TRUE,
cluster = NULL,
pseudo_rsq = FALSE,
tol = 1e-10) {
if (!is.null(subset)) { data <- data[subset, ] }

Expand All @@ -41,6 +44,10 @@ fepois <- function(formula, data,
vardep <- all.vars(formula(formula, lhs = 1, rhs = 0))
vardep <- data[, vardep, drop = TRUE]

if (isTRUE(pseudo_rsq)) {
vardep2 <- vardep
}

if (min(vardep) < 0) {
stop("y should be greater or equals to zero.")
}
Expand Down Expand Up @@ -181,6 +188,10 @@ fepois <- function(formula, data,

names(reg$fitted.values) <- rownames(data)

if (isTRUE(pseudo_rsq)) {
reg$pseudo_rsq <- cor(vardep2, reg$fitted.values, method = "kendall")^2
}

class(reg) <- "fepois"
return(reg)
}
Expand Down
73 changes: 73 additions & 0 deletions dev/test-ppml.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
load_all()

library(dplyr)

ch1_application1 <- tradepolicy::agtpa_applications %>%
select(exporter, importer, pair_id, year, trade, dist, cntg, lang, clny) %>%
filter(year %in% seq(1986, 2006, 4))

ch1_application1 <- ch1_application1 %>%
mutate(
log_trade = log(trade),
log_dist = log(dist)
)

ch1_application1 <- ch1_application1 %>%
# Create Yit
group_by(exporter, year) %>%
mutate(
y = sum(trade),
log_y = log(y)
) %>%

# Create Eit
group_by(importer, year) %>%
mutate(
e = sum(trade),
log_e = log(e)
)

ch1_application1 <- ch1_application1 %>%
# Replicate total_e
group_by(exporter, year) %>%
mutate(total_e = sum(e)) %>%
group_by(year) %>%
mutate(total_e = max(total_e)) %>%

# Replicate rem_exp
group_by(exporter, year) %>%
mutate(
remoteness_exp = sum(dist * total_e / e),
log_remoteness_exp = log(remoteness_exp)
) %>%

# Replicate total_y
group_by(importer, year) %>%
mutate(total_y = sum(y)) %>%
group_by(year) %>%
mutate(total_y = max(total_y)) %>%

# Replicate rem_imp
group_by(importer, year) %>%
mutate(
remoteness_imp = sum(dist / (y / total_y)),
log_remoteness_imp = log(remoteness_imp)
)

ch1_application1 <- ch1_application1 %>%
# This merges the columns exporter/importer with year
mutate(
exp_year = paste0(exporter, year),
imp_year = paste0(importer, year)
)

ch1_application1 <- ch1_application1 %>%
filter(exporter != importer)

fit_ppml <- lfe::fepois(trade ~ log_dist + cntg + lang + clny | exp_year + imp_year,
data = ch1_application1,
cluster = ~pair_id,
pseudo_rsq = T
)

summary(fit_ppml)
4 changes: 4 additions & 0 deletions man/fepois.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 16 additions & 32 deletions src/crowsum.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
// #ifdef _OPENMP
// #include <omp.h>
// #endif
SEXP crowsum(SEXP Rmat, SEXP Rfactor, SEXP Rmean)
{
if (!IS_NUMERIC(Rmat))
error("Only numeric matrices accepted");
SEXP crowsum(SEXP Rmat, SEXP Rfactor, SEXP Rmean) {
if (!IS_NUMERIC(Rmat)) error("Only numeric matrices accepted");
if (!isInteger(Rfactor) && !isFactor(Rfactor))
error("Only factor or integer vector accepted");
R_xlen_t len = xlength(Rmat);
Expand All @@ -19,13 +17,10 @@ SEXP crowsum(SEXP Rmat, SEXP Rfactor, SEXP Rmean)
int *table = NULL;
// int nthr = INTEGER(threads)[0];
mat = REAL(Rmat);
if (isMatrix(Rmat))
{
if (isMatrix(Rmat)) {
cols = ncols(Rmat);
rows = nrows(Rmat);
}
else
{
} else {
cols = 1;
rows = len;
}
Expand All @@ -34,21 +29,15 @@ SEXP crowsum(SEXP Rmat, SEXP Rfactor, SEXP Rmean)

nlev = nlevels(Rfactor);

for (int i = 0; i < rows; i++)
{
if (f[i] < 1 || ISNA(f[i]))
error("Missing levels not supported");
if (f[i] > nlev)
error("Level for %d is %d, too large %d", i, f[i], nlev);
for (int i = 0; i < rows; i++) {
if (f[i] < 1 || ISNA(f[i])) error("Missing levels not supported");
if (f[i] > nlev) error("Level for %d is %d, too large %d", i, f[i], nlev);
}

if (mean)
{
if (mean) {
table = (int *)R_alloc(nlev, sizeof(int));
for (int i = 0; i < nlev; i++)
table[i] = 0;
for (int i = 0; i < rows; i++)
table[f[i] - 1]++;
for (int i = 0; i < nlev; i++) table[i] = 0;
for (int i = 0; i < rows; i++) table[f[i] - 1]++;
}

// Allocate resultant matrix
Expand All @@ -58,29 +47,24 @@ SEXP crowsum(SEXP Rmat, SEXP Rfactor, SEXP Rmean)
SEXP rdn = GET_DIMNAMES(Rmat);
PROTECT(dn = allocVector(VECSXP, 2));
SET_VECTOR_ELT(dn, 0, GET_LEVELS(Rfactor));
if (!isNull(rdn))
SET_VECTOR_ELT(dn, 1, VECTOR_ELT(rdn, 1));
if (!isNull(rdn)) SET_VECTOR_ELT(dn, 1, VECTOR_ELT(rdn, 1));
SET_DIMNAMES(res, dn);
UNPROTECT(1);

mres = REAL(res);
// Now, run through column by column, summing the levels
// #pragma omp parallel for num_threads(nthr)
memset(mres, 0, nlev * cols * sizeof(double));
mres--; // factor levels are 1-based
for (int k = 0; k < cols; k++, mres += nlev)
{
for (int i = 0; i < rows; i++)
{
mres--; // factor levels are 1-based
for (int k = 0; k < cols; k++, mres += nlev) {
for (int i = 0; i < rows; i++) {
mres[f[i]] += *mat++;
}
}
if (mean)
{
if (mean) {
mres = REAL(res);
for (int k = 0; k < cols; k++, mres += nlev)
for (int i = 0; i < nlev; i++)
mres[i] /= table[i];
for (int i = 0; i < nlev; i++) mres[i] /= table[i];
}
UNPROTECT(1);
return (res);
Expand Down
Loading