所以我不确定它是否满足“优雅”的要求,但这是一个通用功能,您可以使用它来获取平衡数据。
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 进行观察(默认),或者如果您将其设置为“共享”,它只会返回所有 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
仅要求所有 PERSON/YEARS 的“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
现在请注意,Edward 是唯一具有 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 年的数据,因为所有人都有这些年份的数据。