Этот вопрос основан на двух предыдущих вопросах, которые я задавал для SO, каждый более сложный, чем предыдущий.В предыдущем посте - Как идентифицировать зеркальные дубликаты строк в R -
Я хотел бы определить «частичные» совпадения строк в кадре данных.В частности, я хочу создать новый столбец со значением TRUE, если конкретная строка в кадре данных имеет повторяющуюся строку где-то еще в кадре данных на основе соответствия между подмножеством столбцов.Дополнительная сложность заключается в том, что один из столбцов в кадре данных является числовым, и я хочу сопоставить, если абсолютные значения совпадают.Проблема заключается в том, что мне нужно убедиться, что, когда строка идентифицируется как частично дублированная, это ТОЛЬКО, если ОДИН из столбцов, являющихся частью совпадения, является зеркально противоположным (аддитивным обратным) значением, а не просто совпадением по абсолютномузначение.В конечном счете, я ищу строки, которые представляют собой пары дубликатов по двум категориальным переменным и являются аддитивными инверсиями по третьей числовой переменной.Чтобы прояснить ситуацию, вот примеры данных:
name<-c("Richard Nixon", "Bill Clinton", "George Bush", "Richard Nixon", "Bill Clinton", "Richard Nixon", "Abe Lincoln","Richard Nixon", "Bill Clinton", "Richard Nixon")
state<-c("California", "Indiana", "Florida", "California", "Indiana", "California","Oregon","California", "Indiana", "California")
num<-c("-258", "123", "42", "258", "123", "-258", "87","258", "-123", "258")
date<-c("day 9", "day 2", "day 15", "day 3","day 45", "day 100", "day 99", "day 10", "day 11", "day 100")
(df <- data.frame(name, state, num, date, stringsAsFactors = FALSE))
name state num date
1 Richard Nixon California -258 day 9
2 Bill Clinton Indiana 123 day 2
3 George Bush Florida 42 day 15
4 Richard Nixon California 258 day 3
5 Bill Clinton Indiana 123 day 45
6 Richard Nixon California -258 day 100
7 Abe Lincoln Oregon 87 day 99
8 Richard Nixon California 258 day 10
9 Bill Clinton Indiana -123 day 11
10 Richard Nixon California 258 day 100
Если бы я запустил отличное решение из предыдущего поставленного мной SO вопроса, это привело бы к следующему
(df %>%
mutate(num = as.numeric(num), num1 = abs(num)) %>%
group_by(name, state, num1) %>%
mutate(newcol = n() > 1 & n_distinct(sign(num)) > 1) %>%
ungroup %>%
select(-num1)) %>%
arrange(name)
# A tibble: 10 x 5
name state num date newcol
<chr> <chr> <dbl> <chr> <lgl>
1 Abe Lincoln Oregon 87 day 99 FALSE
2 Bill Clinton Indiana 123 day 2 TRUE
3 Bill Clinton Indiana 123 day 45 TRUE
4 Bill Clinton Indiana -123 day 11 TRUE
5 George Bush Florida 42 day 15 FALSE
6 Richard Nixon California -258 day 9 TRUE
7 Richard Nixon California 258 day 3 TRUE
8 Richard Nixon California -258 day 100 TRUE
9 Richard Nixon California 258 day 10 TRUE
10 Richard Nixon California 258 day 100 TRUE
.проблема с вышеприведенным выводом состоит в том, что для Ричарда Никсона и для Билла Клинтона есть одна строка, слишком много, где появляется ИСТИНА.Мой желаемый вывод следующий:
name state num date newcol
1 Abe Lincoln Oregon 87 day 99 FALSE
2 Bill Clinton Indiana 123 day 2 TRUE
3 Bill Clinton Indiana 123 day 45 FALSE
4 Bill Clinton Indiana -123 day 11 TRUE
5 George Bush Florida 42 day 15 FALSE
6 Richard Nixon California -258 day 9 TRUE
7 Richard Nixon California 258 day 3 TRUE
8 Richard Nixon California -258 day 100 TRUE
9 Richard Nixon California 258 day 10 TRUE
10 Richard Nixon California 258 day 100 FALSE
Обратите внимание, что только строки, зеркально совпадающие с зеркальным совпадением, совпадают в том смысле, что строки являются дубликатами, за исключением того, что они являются аддитивными инверсиями друг друга для столбца num
.Таким образом, я в основном пытаюсь идентифицировать все строки, которые совпадают вдоль переменных name
и state
и являются аддитивными инверсиями друг друга вдоль переменной num
, с условием, что аддитивные инверсии будут уникальными - уникальными в том смысле, что num
следует считать только аддитивной инверсией не более одной строки.
Для дополнительной ясности, если вышеприведенное объяснение нуждается в разъяснении, в противном случае пропустите:
Таким образом, некоторый процесс, который проходит по каждой строке, идентифицируя первую строку, которая соответствует критериям того, чтобы быть частичнымmatch (частичное в смысле абсолютного значения / аддитивного обратного), а затем присваивает TRUE эти две строки, а затем переходит к следующему наблюдению и так далее.Например, код может начинаться с Abe Lincoln и проходить через каждую последующую строку, пока не будет найдена частично совпадающая строка, если строка не найдена, то в столбце newcol
FALSE
указано значение, которое должно быть сгенерировано.Затем он переходит к Биллу Клинтону, штат Индиана, 123 и проходит по строкам, чтобы определить частичное совпадение.Следующая строка НЕ является частичным совпадением, поскольку 123 и 123 не являются частичными совпадениями (они являются полными совпадениями), но следующая строка является частичным совпадением (123 и -123), в результате чего генерируется значение TRUE
для newcol
для этого наблюдения, а также для частично подобранного ряда.Затем он идет в третий ряд (Билл Клинтон, Индиана, 123).Важной частью этого шага является то, что если строка уже имеет значение для newcol
, цикл не должен проходить через нее.Таким образом, для этой строки (третьей строки) цикл пропустил бы первую строку (с Абэ Линкольном) b / c, которая уже имеет значение FALSE
, и пропустил бы вторую строку и 4-ую строку bc, эти два уже были сопоставленывместе, в результате чего FALSE
для третьей строки b / c, оставшиеся строки не были частично сопоставлены, а единственное частичное совпадение во фрейме данных уже сопоставлено с другой инверсией.