用 R 中的 ID 用 'NA' 替换值

Replacing values with 'NA' by ID in R

我有这样的数据

ID    v1    v2
1     1     0
2     0     1
3     1     0
3     0     1
4     0     1

如果 ID 在数据框中出现多次,我想用 'NA' 替换所有值。最终产品应该是这样的

ID    v1    v2
1     1     0
2     0     1
3     NA    NA
3     NA    NA
4     0     1

我可以手动执行此操作,但我希望 R 检测所有重复的情况(在本例中是 ID“3”的两倍)并将值替换为 'NA'。

感谢您的帮助!

这是一个基本的 R 方法

# get list of repeated IDs
repeats <- rle(df$ID)$values[rle(df$ID)$lengths > 1]

# set the corresponding variables to NA
df[, -1] <- sapply(df[, -1], function(i) {i[df$ID %in% repeats] <- NA; i})

在第一行,我们使用rle来提取重复的ID。在第二种情况下,我们使用 sapply 循环遍历非 ID 变量,并用 NA 替换每个变量重复的 ID。

注意这里假设数据集是按ID排序的。这可以通过 order 函数来完成。 (df <- df[order(df$ID),]).

如果数据集非常大,您可以将第一个函数分成两步以避免计算 rle 两次:

dfRle <- rle(df$ID)
repeats <- dfRle$values[dfRle$lengths > 1]

数据

df <- read.table(header=T, text="ID    v1    v2
1     1     0
2     0     1
3     1     0
3     0     1
4     0     1")

您可以从任一端使用 duplicated(),然后替换。

idx <- duplicated(df$ID) | duplicated(df$ID, fromLast = TRUE)
df[idx, -1] <- NA

这给出了

  ID v1 v2
1  1  1  0
2  2  0  1
3  3 NA NA
4  3 NA NA
5  4  0  1

如果重复的 ID 不相邻,这也适用。

数据:

df <- structure(list(ID = c(1L, 2L, 3L, 3L, 4L), v1 = c(1L, 0L, 1L, 
0L, 0L), v2 = c(0L, 1L, 0L, 1L, 1L)), .Names = c("ID", "v1", 
"v2"), class = "data.frame", row.names = c(NA, -5L))

多一个选项:

df1[df1$ID %in% df1$ID[duplicated(df1$ID)], -1] <- NA
#> df1
#  ID v1 v2
#1  1  1  0
#2  2  0  1
#3  3 NA NA
#4  3 NA NA
#5  4  0  1

数据

df1 <- structure(list(ID = c(1L, 2L, 3L, 3L, 4L), v1 = c(1L, 0L, 1L, 
0L, 0L), v2 = c(0L, 1L, 0L, 1L, 1L)), .Names = c("ID", "v1", 
"v2"), class = "data.frame", row.names = c(NA, -5L))