从多个观察中分配单个ID

时间:2013-07-23 01:26:31

标签: r

我有一个调查数据集,受访者多次出现。受访者由身份证件识别。除此之外,还有第二个变量(IDPREV),它给出了先前识别出被访者的ID(在上次访谈时分配给被访者的ID)。我想为每个受访者创建一个唯一的ID,每次访问受访者时都保持不变。受访者可以在数据集中多次出现。任何建议&我很感激!谢谢!

结构看起来像那样。不幸的是,这种组织不是很好,受访者可以多次出现:

structure(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NA, NA, NA, NA, NA, 
1, 2, 3, 4, 5), .Dim = c(10L, 2L), .Dimnames = list(NULL, c("ID", 
"IDPREV")))

3 个答案:

答案 0 :(得分:4)

这样的事情应该很快收敛:

x      <- ifelse(is.na(df$IDPREV), df$ID, df$IDPREV)
update <- function(x) x[match(x, df$ID)]
y      <- update(x)

while(!identical(y, x)) {
  x <- y
  y <- update(x)
}

df$FINAL_ID <- x

经过测试:

df <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 
                     IDPREV = c(NA, NA, NA, NA, NA, 1, 2, 3, 4, 5, 10, 11)),
                .Names = c("ID", "IDPREV"),
                row.names = c(NA, 12L), class = "data.frame")

最终输出是:

#    ID IDPREV FINAL_ID
# 1   1     NA        1
# 2   2     NA        2
# 3   3     NA        3
# 4   4     NA        4
# 5   5     NA        5
# 6   6      1        1
# 7   7      2        2
# 8   8      3        3
# 9   9      4        4
# 10 10      5        5
# 11 11     10        5
# 12 12     11        5

答案 1 :(得分:1)

您可以将数据对象合并到自身:

 dat <- structure(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NA, NA, NA, NA, NA, 
 1, 2, 3, 4, 5), .Dim = c(10L, 2L), .Dimnames = list(NULL, c("ID", 
 "IDPREV")))
 dat2 <- merge(dat, dat, by.x=1, by.y=2)
Warning message:
In merge.data.frame(as.data.frame(x), as.data.frame(y), ...) :
  column name ‘ID’ is duplicated in the result

 dat2
#-----------------
  ID IDPREV ID
1  1     NA  6
2  2     NA  7
3  3     NA  8
4  4     NA  9
5  5     NA 10

您可能希望为第二个“ID”变量创建更具信息性的列名。

 names(dat)[3] <- "Second.ID"

答案 2 :(得分:1)

这也可以概念化为图形对象,并允许使用igraph包。例如,使用@ flodel的回答数据。

df <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 
                     IDPREV = c(NA, NA, NA, NA, NA, 1, 2, 3, 4, 5, 10, 11)),
                .Names = c("ID", "IDPREV"),
                row.names = c(NA, 12L), class = "data.frame")

require(igraph)    
# get rid of the effect of the NAs by matching these cases 
# back to themselves; make a graph; then extract the clusters
df$IDPREV[is.na(df$IDPREV)] <- df$ID[is.na(df$IDPREV)]
g.el <- graph.data.frame(df)
df$FINAL_ID_LM <- clusters(g.el)$membership

给出与@ flodel的答案相同的结果:

> df
   ID IDPREV FINAL_ID_LM FINAL_ID_FL
1   1      1           1           1
2   2      2           2           2
3   3      3           3           3
4   4      4           4           4
5   5      5           5           5
6   6      1           1           1
7   7      2           2           2
8   8      3           3           3
9   9      4           4           4
10 10      5           5           5
11 11     10           5           5
12 12     11           5           5