#r #vector
#r #вектор
Вопрос:
У меня есть набор данных с одним столбцом идентификатора, 12 информационными столбцами (строками) и n строками. Это выглядит так:
ID Col1 Col2 Col3 Col4 Col5 ...
01 a b c d a
02 a a a a a
03 b b b b b
...
Мне нужно перейти строка за строкой и проверить, равна ли эта строка (учитывая все ее столбцы) любой другой строке в наборе данных. Моим выводом должны быть два новых столбца: один, указывающий, равна ли эта конкретная строка любой другой строке, и второй столбец, указывающий, какой строке он равен (в случае TRUE в предыдущем столбце)
Я ценю любые предложения.
Комментарии:
1. Является ли ID первичным или уникальным ключом?
2. Не могли бы вы предоставить полный пример фрейма данных с ожидаемым результатом?
3. ID — это уникальный ключ.
Ответ №1:
Предполагая DF
, что в примечании в конце, отсортируйте его и создайте столбец dup
, указывающий, существует ли предыдущая повторяющаяся строка. Затем установите wx
значение равным номеру строки в исходном фрейме данных дубликата. Наконец, вернитесь назад.
Мы предположили, что дублирование означает, что столбцы, отличные от идентификатора, одинаковы, но при необходимости их можно легко изменить. Мы также предположили, что мы должны пометить вторую и последующие строки среди дубликатов, тогда как первая не помечена так, потому что на данный момент у нее нет дубликатов.
Вопрос не касается ситуации с более чем 2 одинаковыми строками, но если такая ситуация существует, то каждый дубликат будет указывать на ближайшую предыдущую строку, в которой он является дубликатом.
o <- do.call("order", DF[-1])
DFo <- DF[o, ]
DFo$wx <- DFo$dup <- duplicated(DFo)
DFo$wx[DFo$dup] <- as.numeric(rownames(DFo))[which(DFo$dup) - 1]
DFo[order(o), ] # back to original order
предоставление:
ID Col1 Col2 Col3 Col4 Col5 dup wx
1 1 a b c d a FALSE 0
2 2 a a a a a FALSE 0
3 3 b b b b b FALSE 0
4 1 a b c d a TRUE 1
Примечание
Lines <- "ID Col1 Col2 Col3 Col4 Col5
01 a b c d a
02 a a a a a
03 b b b b b"
DF <- read.table(text = Lines, header = TRUE)
DF <- DF[c(1:3, 1), ]
rownames(DF) <- NULL
предоставление:
> DF
ID Col1 Col2 Col3 Col4 Col5
1 1 a b c d a
2 2 a a a a a
3 3 b b b b b
4 1 a b c d a
Ответ №2:
С df
подобным ниже:
ID Col1 Col2 Col3 Col4 Col5
1 1 a b c d a
2 2 a a a a a
3 3 b b b b b
4 3 b b b b b
Вы можете попробовать группировку по всем столбцам и проверить, есть ли какие-либо подсчеты > 1
, а также вставить номера строк ( 1:nrow(df)
):
df <- transform(
df,
dupe = ave(ID, mget(names(df)), FUN = length) > 1,
dupeRows = ave(1:nrow(df), mget(names(df)), FUN = toString)
)
Поскольку это даст вам число для каждой строки, даже если дубликатов нет, вы могли бы сделать:
df$dupeRows <- with(df,
Map(function(x, y)
toString(x[x != y]),
strsplit(as.character(dupeRows), split = ', '),
1:nrow(df)))
Вывод:
ID Col1 Col2 Col3 Col4 Col5 dupe dupeRows
1 1 a b c d a FALSE
2 2 a a a a a FALSE
3 3 b b b b b TRUE 4
4 3 b b b b b TRUE 3
Данные
df <- structure(list(ID = c(1L, 2L, 3L, 3L), Col1 = structure(c(1L,
1L, 2L, 2L), .Label = c("a", "b"), class = "factor"), Col2 = structure(c(2L,
1L, 2L, 2L), .Label = c("a", "b"), class = "factor"), Col3 = structure(c(3L,
1L, 2L, 2L), .Label = c("a", "b", "c"), class = "factor"), Col4 = structure(c(3L,
1L, 2L, 2L), .Label = c("a", "b", "d"), class = "factor"), Col5 = structure(c(1L,
1L, 2L, 2L), .Label = c("a", "b"), class = "factor")), row.names = c(NA,
-4L), class = "data.frame")
Ответ №3:
Решение dplyr
library(dplyr)
df %>%
mutate(row_num = 1:n(), is_dup = duplicated(df)) %>%
group_by(across(-c(row_num, is_dup))) %>%
mutate(
has_copies = n() > 1L,
which_row = if_else(is_dup, first(row_num), NA_integer_),
row_num = NULL, is_dup = NULL
)
Вывод
# A tibble: 5 x 8
# Groups: ID, Col1, Col2, Col3, Col4, Col5 [3]
ID Col1 Col2 Col3 Col4 Col5 has_copies which_row
<chr> <fct> <fct> <fct> <fct> <fct> <lgl> <int>
1 1 a b c d a FALSE NA
2 2 a a a a a FALSE NA
3 3 b b b b b TRUE NA
4 3 b b b b b TRUE 3
5 3 b b b b b TRUE 3
-
Для каждой строки, имеющей более одной копии, значение
has_copies
aTRUE
. -
Для набора одинаковых строк я рассматриваю первую строку как исходную, а все остальные строки — как дубликаты. В связи с этим,
which_row
дает вам индекс оригинала для каждого найденного дубликата. Другими словами, если строка не имеет дубликатов или является оригиналом, это дает вамNA
.