Пропорциональный и двоичный ответ с pglm

Я работаю с панельными данными, включающими наблюдения за школами за несколько лет. Мой DV — это доля сдавших экзамен, но она не распределяется нормально, и многие наблюдения за DV составляют > 0,8. Таким образом, панельная линейная модель с использованием plm() (из пакета plm) неуместна, поэтому я пытаюсь -of-model/" rel="nofollow noreferrer">рассматривать DV как бинарный ответ и использовать логистическую регрессию с pglm() (из пакета pglm). У меня есть подсчет количества сдавших и прошедших тест.

Я решил, что мне нужно использовать оценку с фиксированными эффектами (внутри модуля) для этих данных, поскольку меня интересует среднее изменение показателей сдачи экзаменов в школах. У меня слишком много наблюдений, чтобы опубликовать полный набор данных, но вот небольшой воспроизводимый пример сообщения об ошибке:

id <- c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4)
year <- rep(c(2017, 2018, 2019), 4)
proportion <- c(.67, .77, .79, .88, .89, .85, .79, .81, .79, .87, .75, .74)
X1 <- c(.05, .041, .037, .015, .012, .021, .081, .055, .062, .034, .031, .022)
X2 <- c(145, 146, 145, 155, 154, 154, 150, 152, 156, 148, 150, 151)
takers <- c(50, 62, 55, 112, 101, 119, 44, 45, 48, 66, 69, 60)
passers <- c(34, 48, 43, 99, 90, 101, 35, 36, 38, 57, 52, 44)
fails <- takers - passers

data <- as.data.frame(cbind(id, year, proportion, X1, X2, takers, passers, fails))

pglm::pglm(cbind(passers, fails) ~ X1 + X2, index = c("id", "year"), model = "within",  family = binomial(link = "logit"), data = data)
#> Error in `.rowNamesDF<-`(x, value = value): duplicate 'row.names' are not allowed

Создано 21 октября 2020 г. с помощью пакета reprex (v0.3.0)

Я не сталкиваюсь с проблемой запуска обычного логита:

glm(cbind(passers, fails) ~ X1 + X2,family = binomial(link = "logit"), data = data)

И я также знаком с альтернативой подходу трактовать DV как двоичный, а именно с пакетом betareg(), который использует бета-регрессию]2, но я не вижу смысла использовать фиксированные эффекты с betareg(). Я также могу запустить этот код, используя glmer() и установив случайный перехват (1 | id), но подход со случайными эффектами не имеет теоретического смысла, учитывая мой исследовательский вопрос, а тест Хаусмана показывает, что мне все равно нужны фиксированные эффекты.

Моя интерпретация сообщения об ошибке заключается в том, что имена строк каким-то образом дублируются; Я убедился, что это не так, установив для всех имен строк значение NULL, но это не решило проблему:

row.names(data) <- NULL

Я также сослался на, казалось бы, похожие вопросы по этой проблеме такие как этот, но Я убедился, что в паре id-year нет дубликатов.

Таким образом, любая помощь в выяснении того, что такое ошибка, будет высоко оценена. Комментарии по методологии, конечно, тоже приветствуются.


person Josh J    schedule 22.10.2020    source источник
comment
Чего вы хотите добиться с помощью cbind(passers, fails) в формуле? Вы смотрели на результат только этой команды? Какова будет доля успешно сдавших экзамены? Хотя подобная спецификация поддерживается glm (см. ?glm), она не поддерживается в pglm.   -  person Helix123    schedule 22.10.2020
comment
Привет, Helix, просто запуск этой команды возвращает матрицу прохожих 12x2 и терпит неудачу. Там я просто пытаюсь заставить функцию pglm прогнозировать сдачу экзамена на основе наблюдаемой вероятности сдачи в этой школе. Я сам не привык к такому подходу, но читал об этом в источниках, на которые я ссылаюсь в своем посте. Если pglm не поддерживает это (и спасибо за эту информацию), можете ли вы порекомендовать лучший способ продолжить?   -  person Josh J    schedule 22.10.2020


Ответы (1)


Сообщение об ошибке о дублирующихся именах строк немного вводит в заблуждение, поскольку pglm не может обрабатывать определенные входные данные, которые glm может обрабатывать с помощью матрицы из двух столбцов, определяющей пропорцию (cbind(passers, fails) в вашем коде). glm является более гибким в отношении различных возможностей ввода, см. ?glm.

pglm может обрабатывать только двоичную зависимую переменную в качестве входных данных в левой части формулы. Таким образом, вы хотите свести данные к индивидуальному уровню (вот более подробное обсуждение темы с индивидуальным результатом (бинарный ответ) и групповым результатом (пропорция), используя glm http://www.simonqueenborough.info/R/statistics/lessons/Binomial_Data.html; http://pages.stat.wisc.edu/%7Emchung/teaching/MIA/reading/GLM.logistic.Rpackage.pdf).

Вот некоторый код, который дает вам преобразование данных для репликации модели, которую вы оценили, используя glm с pglm. Посмотрите, как общее количество экзаменов takers (passers и fails) используется для сведения данных к индивидуальному результату (двоичный response) с уровня группы (proportion).

# glm - your reference
summary(mod1 <- glm(cbind(passers, fails) ~ X1 + X2, family = binomial(link = "logit"), data = data))
# glm - same with weights
data$prop <- data$passers / data$takers
summary(mod2 <- glm(prop ~ X1 + X2, family = binomial(link = "logit"), data = data, weights = takers))

# construct data suitable for pglm
df2 <- df[rep(seq_along(data$takers), data$takers), ]
df2$ID <- paste(df2$id, unlist(lapply(df$takers, seq_len)), sep = '')
vec <- numeric()
for (i in 1:nrow(data)) {
    vec  <- c(vec, (c(rep(1, data$passers[i]), rep(0, data$fails[i]))))
}
df2$resp <- vec  
pdf2 <- pdata.frame(df2, index = "id")

# same with pglm
summary(mod3 <- pglm(resp ~ X1 + X2, family = binomial(link = "logit"), data = pdf2, model = "pooling"))

Если вы хотите оценить какую-либо другую модель, кроме модели "pooling", вам потребуется построить другой индекс (иначе вы получите неверные результаты, как я полагаю), для которого у вас может не быть информации (индивидуальные комбинации времени для всех строк). в pdf2/df2).

person Helix123    schedule 22.10.2020