所以我不确定它是否满足“优雅”的要求,但这里有一个通用函数可以用来获得平衡的数据。
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(unbal, "PERSON","YEAR")
# PERSON YEAR Y X
# 1 Frank 2001 21 1
# 2 Frank 2002 22 2
# 3 Frank 2003 23 3
# 4 Frank 2004 24 4
# 5 Frank 2005 25 5
# 11 Edward 2001 31 11
# 12 Edward 2002 32 12
# 13 Edward 2003 33 13
# 14 Edward 2004 34 14
# 15 Edward 2005 35 15
得到你想要的结果的第一个参数是要子集data.frame。第二个参数(ID=
)是标识数据集中每个“人员”的列名的字符向量。然后,TIME=
参数也是一个字符向量,用于指定每个ID的不同观察时间。最后,您可以选择指定VARS=
参数来指定哪些字段必须是NA(默认为ID或TIME值以外的所有字段)。最后,还有一个名为required
的最后一个参数,它说明每个ID对每个TIME(默认值)都必须有一个观察值,还是将其设置为“shared”,它将只返回所有ID都具有非缺失值的TIMES。
因此,例如
balanced(unbal, "PERSON","YEAR", "X")
# PERSON YEAR Y X
# 1 Frank 2001 21 1
# 2 Frank 2002 22 2
# 3 Frank 2003 23 3
# 4 Frank 2004 24 4
# 5 Frank 2005 25 5
# 6 Tony 2001 5 6
# 7 Tony 2002 6 7
# 8 Tony 2003 NA 8
# 9 Tony 2004 7 9
# 10 Tony 2005 8 10
# 11 Edward 2001 31 11
# 12 Edward 2002 32 12
# 13 Edward 2003 33 13
# 14 Edward 2004 34 14
# 15 Edward 2005 35 15
只需要在“X”是NA所有人/年,因为这是所有记录真实的,没有子设置发生。
如果你
balanced(unbal, "PERSON","YEAR", required="shared")
# PERSON YEAR Y X
# 1 Frank 2001 21 1
# 2 Frank 2002 22 2
# 4 Frank 2004 24 4
# 5 Frank 2005 25 5
# 6 Tony 2001 5 6
# 7 Tony 2002 6 7
# 9 Tony 2004 7 9
# 10 Tony 2005 8 10
# 11 Edward 2001 31 11
# 12 Edward 2002 32 12
# 14 Edward 2004 34 14
# 15 Edward 2005 35 15
那么你得到2001年,2002年,2004年,2005年所有人的数据,因为他们都对这些年的数据。
现在让我们用创造一个稍微不同的样本数据集
unbal2 <- unbal
unbal2[15, 2] <- 2006
tail(unbal2)
# PERSON YEAR Y X
# 10 Tony 2005 8 10
# 11 Edward 2001 31 11
# 12 Edward 2002 32 12
# 13 Edward 2003 33 13
# 14 Edward 2004 34 14
# 15 Edward 2006 35 15
注意,现在爱德华是具有价值在2006年的唯一的人这意味着
balanced(unbal2, "PERSON","YEAR")
# [1] PERSON YEAR Y X
# <0 rows> (or 0-length row.names)
现在返回什么,但
balanced(unbal2, "PERSON","YEAR", required="shared")
# PERSON YEAR Y X
# 1 Frank 2001 21 1
# 2 Frank 2002 22 2
# 4 Frank 2004 24 4
# 6 Tony 2001 5 6
# 7 Tony 2002 6 7
# 9 Tony 2004 7 9
# 11 Edward 2001 31 11
# 12 Edward 2002 32 12
# 14 Edward 2004 34 14
将返回2001,2002,2004的数据,因为所有人都有数据fo那些年。
如果问津倒过来(使不平衡的面板通过在港定居填充平衡),可以使用该功能使' .pm包中的.pbalanced'(需要https://r-forge.r-project.org/R/?group_id=406的最新开发版本) – Helix123 2016-06-28 19:32:11
plm的官方CRAN版本(1.6-4)现在拥有' make.pbalanced '并入(并通过参数'balance.type = c(“fill”,“shared”)'可以选择是扩展数据还是减少数据。 – Helix123 2016-11-30 08:22:50