Как я могу сбалансировать панель, которая не сбалансирована в R?
У меня есть несбалансированные месячные данные панели. В некоторых штатах отсутствуют некоторые периоды времени, и поэтому у меня нет этих периодов в моей группе. Я хотел бы добавить эти периоды и назначить им NA
значение.
Я пробовал функцию, которая балансирует панель, но она устраняет все наблюдения, которые не соответствуют всем состояниям. Поэтому, если не будет данных по Алабаме за 02-2008 годы, это исключит наблюдения для всех штатов за 02-2008.
balanced <- function(data, ID, TIME, VARS, required=c("all", "shared")) {
if(is.character(ID)) {
ID <- match(ID, names(data))
}
if(is.character(TIME)) {
TIME <- match(TIME, names(data))
if(missing(VARS)) {
VARS <- setdiff(1:ncol(data), c(ID,TIME))
} else if (is.character(VARS)) {
VARS <- match(VARS, names(data))
}
required <- match.arg(required)
idf <- do.call(interaction, c(data[, ID, drop=FALSE], drop=TRUE))
timef <- do.call(interaction, c(data[, TIME, drop=FALSE], drop=TRUE))
complete <- complete.cases(data[, VARS])
tbl <- table(idf[complete], timef[complete])
if (required == "all") {
keep <- which(rowSums(tbl == 1) == ncol(tbl))
idx <- as.numeric(idf) %in% keep
} else if (required == "shared") {
keep <- which(colSums(tbl == 1) == nrow(tbl))
idx <- as.numeric(timef) %in% keep
}
data[idx, ]
}
Balanced_panel <- balanced(milk_state, "STATE", "PERIOD", "VALUE", required = "all")
Вот как это выглядит:
STATE PERIOD VALUE
California 01-2018 900
California 02-2018 890
California 03-2018 780
California 05-2018 800
Вот как я хочу, чтобы это выглядело так:
STATE PERIOD VALUE
California 01-2018 900
California 02-2018 890
California 03-2018 780
California 04-2018 NA
California 05-2018 800
1 ответ
На самом деле вы не хотите создавать сбалансированную выборку из существующих данных (это то, что вы сделали с вашим кодом выше), но вы хотели бы расширить свою выборку всеми возможными комбинациями
STATE
а также
PERIOD
. Для этого требуется еще один шаг, а именно создание этих комбинаций. Начните с этого
library(tidyverse)
data$ID %>% unique() %>%
expand.grid(., seq('2018-01-01', '2018-05-01', by = 'month')) %>%
rename("ID" = 1, "PERIOD" = 2) -> df
После этого возьмите этот кадр данных из всех возможных комбинаций,
df
, и используйте
left_join
чтобы присоединиться к вашим существующим наблюдениям:
df %>%
left_join (data, by = c("ID", "PERIOD") -> data
Полученный кадр данных,
data
, представляет собой сбалансированную выборку, содержащую все идентификаторы и периоды. Для вычислений вы могли бы ввести среднее или нулевое вменение пропущенных значений, если ваши настройки допускают такие предположения о значениях переменных, и у вас есть сбалансированная выборка в том узком смысле, что в вашей выборке существуют только идентификаторы с наблюдениями за все периоды.