3

我有一个调查数据集,其中受访者多次出现。受访者由 ID 标识。除此之外,还有第二个变量 (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")))
4

3 回答 3

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
于 2013-07-23T01:57:21.020 回答
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"
于 2013-07-23T01:56:46.357 回答
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
于 2013-07-23T03:20:42.503 回答