使用 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次;根据我的命令,它只出现了两次,因为在第一年 nordp
是 NA
.
我们希望为个人分配唯一 ID,然后按唯一 ID 的数量进行过滤。主要思想是将多年来每个家庭中的 nordp
和 nord
值链接在一起。这是受 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
是同一个人,通过将多年来的 nordp
和 nord
链接在一起,并为所有 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
我正在使用一项全国调查来 运行 回归:该调查每两年进行一次,一些人被反复采访,而另一些人只接受一次。
现在我想把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次;根据我的命令,它只出现了两次,因为在第一年 nordp
是 NA
.
我们希望为个人分配唯一 ID,然后按唯一 ID 的数量进行过滤。主要思想是将多年来每个家庭中的 nordp
和 nord
值链接在一起。这是受 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
是同一个人,通过将多年来的 nordp
和 nord
链接在一起,并为所有 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