R выборка из несбалансированных панельных данных

Я работаю с несбалансированными панельными данными, из которых я хотел бы извлечь случайную выборку, которая не зависит от различного количества наблюдений на единицу. Например, в приведенном ниже коде вероятность выбора 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), ]

person user1491868    schedule 11.12.2013    source источник


Ответы (2)


Вот что можно было сделать:

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
person Julius Vainora    schedule 11.12.2013
comment
Очень интересно. Что делает probs ‹- 1 / table (df $ COMPANY) [df $ COMPANY]? - person user1491868; 11.12.2013

Я просто новый пользователь R, но вот мое решение:

загрузить данные примера (на основе PSID). данные являются несбалансированными панельными данными: 98 индивидуальных наблюдений, 15 групп, в период с 1977 по 1983 год с гендерной идентификацией (не используется)

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")

создать фрейм данных с 1 наблюдением на каждый идентификатор группы (в этом примере 15 отдельных групп)

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

создать выборку из 5 случайных наблюдений из 15

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

объединить m: 1 старый фрейм данных с образцом фрейма данных

df_new <- merge(x = df, y = sample, by = "id", all.y = TRUE)
person overeducatedpoverty    schedule 18.02.2016