使用 NA 过滤 df 以仅获取在 r 中出现多次的个体

filter a df with NA to get only individuals that appear more than one time in r

我正在使用一项全国调查来 运行 回归:该调查每两年进行一次,一些人被反复采访,而另一些人只接受一次。

现在我想把df做成panel one(只有出现不止一次的个体)。 df是这样的:

year  nquest nord nordp sex age
  2000   10    1     1   F  40
  2000   10    2     2   M  43
  2000   30    1     1   M  30
  2002   10    1     1   F  42
  2002   10    2     2   M  45
  2002   10    3     NA  F  15
  2002   30    1     1   M  32
  2004   10    1     1   F  44
  2004   10    2     2   M  47
  2004   10    3     3   F  17
  2004   50    1     NA  M  66

其中nquest是家庭的代码,nord是个人的代码,nordp是个人在上次调查中的代码;当采访新人时,nordp 中的值为 "missing"(R 自动插入 NA)。例如,家庭 10 的个人 3 在 2002 年有 nordp=NA,因为这是她第一次接受采访,而在 2004 年 nordp 是 3(因为 3 是她在 2002 年的号码)。

我无法使用 nord 来过滤 df,因为家庭的组成可能会发生变化(例如在 2002 年的家庭 x 中,母亲的 nordp=2(这意味着在 2000 年 nord 是 2)并且 nord= 2 但下一年 nord 可能是 1(例如,如果她离婚了)但 nordp 仍然是 2)。

我尝试使用此命令进行过滤:

df <- df %>%
group_by(nquest, nordp)
filter(n()>1)

但我没有得到正确的 df,因为如果对于同一个家庭有多个单独插入 (NA),他们将被视为同一个人,因为 nordp 是第一次 NA。

如何也考虑某年首次出现的个体(nordp=NA)?

考虑到 df 由数千个观察值组成,我无法手动检查。

最后的df应该是:

  year  nquest nordp sex age
  2000   10      1        F  40
  2000   10      2        M  43
  2000   30      1        M  30
  2002   10      1        F  42
  2002   10      2        M  45
  2002   10      3        F  15
  2002   30      1        M  32
  2004   10      1        F  44
  2004   10      2        M  47
  2004   10      3        F  17

如你所见,只有出现1次以上的个体,nquest=10 nordp=30出现了3次;根据我的命令,它只出现了两次,因为在第一年 nordpNA.

我们希望为个人分配唯一 ID,然后按唯一 ID 的数量进行过滤。主要思想是将多年来每个家庭中的 nordpnord 值链接在一起。这是受 Identify groups of linked episodes which chain together 启发的想法。首先,通过 library(igraph) 加载 igraph 包。然后下面的函数为给定的家庭分配 ID。

assignID <- function(d) {
  fields <- names(d) # store original column names
  d$nordp[is.na(d$nordp)] <- seq_len(sum(is.na(d$nordp))) + 100
  d$nordp_x <- (d$year-2) * 1000 + d$nordp
  d$nord_x <- d$year * 1000 + d$nord
  dd <- d[, c("nordp_x", "nord_x")]
  gr.test <- graph.data.frame(dd)
  links <- data.frame(org_id = unique(unlist(dd)),
                      id = clusters(gr.test)$membership)
  d <- merge(d, links, by.x = "nord_x", by.y = "org_id", all.x = TRUE)
  d$uid <- d$nquest * 100 + d$id
  d[, c(fields, "uid")]
}

函数可以"tell",例如

year  nordp  nord
2000      1     1
2002      1     2
2004      2     3

是同一个人,通过将多年来的 nordpnord 链接在一起,并为所有 3 行分配相同的唯一 ID。所以,例如,

assignID(subset(df, nquest == 10))
#   year nquest nord nordp sex age  dob  uid
# 1 2000     10    1     1   F  40 1960 1001
# 2 2000     10    2     2   M  43 1957 1002
# 3 2002     10    1     1   F  42 1960 1001
# 4 2002     10    2     2   M  45 1957 1002
# 5 2002     10    3   101   F  15 1987 1003
# 6 2004     10    1     1   F  44 1960 1001
# 7 2004     10    2     2   M  47 1957 1002
# 8 2004     10    3     3   F  17 1987 1003

为我们提供了一个额外的列,每个人都有 uid

剩下的步骤很简单。我们按 nquest 拆分数据帧,将 assignID 应用于每个子集,然后 rbind 输出:

dd <- do.call(rbind, by(df, df$nquest, assignID))

然后我们可以按 uid 分组并按计数过滤:

dd %>% group_by(uid) %>% filter(n()>1)
# Source: local data frame [10 x 8]
# Groups: uid [4]

#     year nquest  nord nordp    sex   age   dob   uid
#    <int>  <int> <int> <dbl> <fctr> <int> <int> <dbl>
# 1   2000     10     1     1      F    40  1960  1001
# 2   2000     10     2     2      M    43  1957  1002
# 3   2002     10     1     1      F    42  1960  1001
# 4   2002     10     2     2      M    45  1957  1002
# 5   2002     10     3   101      F    15  1987  1003
# 6   2004     10     1     1      F    44  1960  1001
# 7   2004     10     2     2      M    47  1957  1002
# 8   2004     10     3     3      F    17  1987  1003
# 9   2000     30     1     1      M    30  1970  3001
# 10  2002     30     1     1      M    32  1970  3001