5

我正在处理不平衡的面板数据,我想从中抽取一个随机样本,该样本不受每单位不同观察次数的影响。例如,在下面的代码中,IBM 被选中的可能性是 GOOG 的两倍,被选中的可能性是 MSFT 的五倍。有没有办法对这些数据进行抽样,就好像每家公司/年份都有相同的被选中的概率?可能通过使用采样包?

df <- data.frame(COMPANY=c(rep('IBM',50),rep('GOOG',25),rep('MSFT',10)), YEAR=c(1961:2010,1988:2012,1996:2005), PROFIT=rnorm(85))
df

df[sample(nrow(df), 20, replace=FALSE), ]
4

2 回答 2

3

这是您可以执行的操作:

probs <- 1 / table(df$COMPANY)[df$COMPANY]
df[sample(nrow(df), 20, replace = FALSE, prob = probs), ]

让我们测试一下:

table(df[sample(nrow(df), 1e6, replace = TRUE, prob = probs), "COMPANY"])
#   GOOG    IBM   MSFT 
# 333499 333080 333421

我们不是让每一行的概率等于 1/(50+25+10),而是将它们归一化,以便每家公司都有相同的概率被选中:

tapply(probs, df$COMPANY, sum)
# GOOG  IBM MSFT 
#   1    1    1

probs总和为 3 而不是 1,但要sample注意这一点)。为了让数学更清楚,让我们举一个简单的例子(它的总和也不等于 1,但这不是问题):

vec <- c(1, 1, 2)
as.vector(1 / table(vec)[vec])
# [1] 0.5 0.5 1.0
于 2013-12-11T19:35:54.937 回答
1

我只是一个新的 R 用户,但这是我的解决方案:

加载示例数据(基于 PSID)。数据是不平衡的面板数据:1977 年至 1983 年间 98 个个人观察,15 个组,有性别识别(未使用)

df <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 5L, 5L, 5L, 5L, 5L,5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L,8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L,10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L,12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 13L,13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L,15L, 15L), year = c(1978L, 1979L, 1980L, 1981L, 1982L, 1983L,1977L, 1978L, 1979L, 1980L, 1981L, 1982L, 1983L, 1977L, 1978L,1979L, 1980L, 1981L, 1982L, 1983L, 1979L, 1977L, 1978L, 1979L,1980L, 1981L, 1982L, 1983L, 1977L, 1978L, 1979L, 1980L, 1981L,1982L, 1983L, 1977L, 1978L, 1979L, 1980L, 1981L, 1982L, 1983L,1977L, 1978L, 1979L, 1980L, 1981L, 1982L, 1983L, 1977L, 1978L,1979L, 1980L, 1981L, 1982L, 1983L, 1977L, 1978L, 1979L, 1980L,1981L, 1982L, 1983L, 1977L, 1978L, 1979L, 1980L, 1981L, 1982L,1983L, 1977L, 1978L, 1979L, 1980L, 1981L, 1982L, 1983L, 1977L,1978L, 1979L, 1980L, 1981L, 1982L, 1983L, 1977L, 1978L, 1979L,1980L, 1981L, 1982L, 1983L, 1977L, 1978L, 1979L, 1980L, 1981L,1982L, 1983L), gender = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L,2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L,1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L,2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)), .Names = c("id", "year","gender"), row.names = c(NA, 98L), class = "data.frame")

创建每个组 id 有 1 个观察值的数据框(在此示例中,有 15 个不同的组)

sample <- select(df, id) %>% group_by(id) %>% sample_n(1) 

从 15 个随机观察中创建 5 个样本

sample <- ungroup(sample) %>% sample_n(5) %>% mutate(id=row_number())

将 m:1 旧数据框与样本数据框合并

df_new <- merge(x = df, y = sample, by = "id", all.y = TRUE)
于 2016-02-18T14:54:26.990 回答