Мы можем независимо друг от друга sort()
каждая строка, а затем использовать !
duplicated()
, чтобы найти, какие строки для сохранения:
df[!duplicated(t(apply(df[1:2],1L,sort))),];
## A B prob
## 1 1 2 0.1
## 2 1 3 0.2
## 3 1 4 0.3
## 5 2 3 0.1
## 6 2 4 0.4
данных
df <- data.frame(A=c(1L,1L,1L,2L,2L,2L),B=c(2L,3L,4L,1L,3L,4L),prob=c(0.1,0.2,0.3,0.3,0.1,0.4
));
Объяснение
Первый шаг должен извлечь только две колонки, представляющие интерес:
df[1:2];
## A B
## 1 1 2
## 2 1 3
## 3 1 4
## 4 2 1
## 5 2 3
## 6 2 4
Тогда мы самостоятельно сортировать каждую строку с apply()
и sort()
:
apply(df[1:2],1L,sort);
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 1 1 1 2 2
## [2,] 2 3 4 2 3 4
Как вы можете видеть, apply()
возвращает свои результаты в неожиданные перестановки, так что мы должны исправить с t()
подготовиться к предстоящей duplicated()
вызова:
t(apply(df[1:2],1L,sort));
## [,1] [,2]
## [1,] 1 2
## [2,] 1 3
## [3,] 1 4
## [4,] 1 2
## [5,] 2 3
## [6,] 2 4
Теперь мы можем использовать duplicated()
, чтобы получить логический вектор, указывающий, какие строки являются дубликатами предыдущих строк:
duplicated(t(apply(df[1:2],1L,sort)));
## [1] FALSE FALSE FALSE TRUE FALSE FALSE
Затем инвертировать логический вектор с отрицанием, чтобы получить только те строки, которые не дубликатами все предыдущие строки:
!duplicated(t(apply(df[1:2],1L,sort)));
## [1] TRUE TRUE TRUE FALSE TRUE TRUE
Наконец, мы можем использовать полученный логический вектор индексировать только те из рядов df
, которые не являются дубликатами всех предыдущих строк:
df[!duplicated(t(apply(df[1:2],1L,sort))),];
## A B prob
## 1 1 2 0.1
## 2 1 3 0.2
## 3 1 4 0.3
## 5 2 3 0.1
## 6 2 4 0.4
Поэтому первый будет сохраняться каждый набор после сортировки, остальная часть будет удалена.
Отличное предложение от @RichardScriven; мы можем заменить t()
вызов с MARGIN
аргументом duplicated()
, который, вероятно, будет немного быстрее:
df[!duplicated(apply(df[1:2],1L,sort),MARGIN=2L),];
## A B prob
## 1 1 2 0.1
## 2 1 3 0.2
## 3 1 4 0.3
## 5 2 3 0.1
## 6 2 4 0.4
Я не уверен, что это то, что вы хотите, но моя первая мысль заключалась в том, чтобы удалить только все строки, где 'B' меньше, чем' A'. –
К сожалению, в моей фактической проблеме столбики a и b не являются номерами, они являются кодами продуктов – Mukul