Удаление дублированных строк с помощью dplyr
У меня есть data.frame, как это -
set.seed(123)
df = data.frame(x=sample(0:1,10,replace=T),y=sample(0:1,10,replace=T),z=1:10)
> df
x y z
1 0 1 1
2 1 0 2
3 0 1 3
4 1 1 4
5 1 0 5
6 0 1 6
7 1 0 7
8 1 0 8
9 1 0 9
10 0 1 10
Я хотел бы удалить повторяющиеся строки на основе первых двух столбцов. Ожидаемый результат -
df[!duplicated(df[,1:2]),]
x y z
1 0 1 1
2 1 0 2
4 1 1 4
Я специально ищу решение с помощью пакета dplyr
.
Ответы
Ответ 1
Примечание: dplyr
теперь содержит distinct
функцию для этой цели.
Оригинальный ответ ниже:
library(dplyr)
set.seed(123)
df <- data.frame(
x = sample(0:1, 10, replace = T),
y = sample(0:1, 10, replace = T),
z = 1:10
)
Один из подходов состоит в том, чтобы сгруппировать, а затем оставить только первый ряд:
df %>% group_by(x, y) %>% filter(row_number(z) == 1)
## Source: local data frame [3 x 3]
## Groups: x, y
##
## x y z
## 1 0 1 1
## 2 1 0 2
## 3 1 1 4
(В dplyr 0.2 вам не понадобится фиктивная переменная z
и вы сможете просто написать row_number() == 1
)
Я также думал о добавлении функции slice()
которая бы работала так:
df %>% group_by(x, y) %>% slice(from = 1, to = 1)
Или, возможно, вариант unique()
, который позволит вам выбрать, какие переменные использовать:
df %>% unique(x, y)
Ответ 2
Вот решение, использующее dplyr 0.3
.
library(dplyr)
set.seed(123)
df <- data.frame(
x = sample(0:1, 10, replace = T),
y = sample(0:1, 10, replace = T),
z = 1:10
)
> df %>% distinct(x, y)
x y z
1 0 1 1
2 1 0 2
3 1 1 4
Обновлено для dplyr 0.5
dplyr версия 0.5 поведение по умолчанию distinct()
возвращает только столбцы, указанные в аргументе ...
.
Чтобы достичь первоначального результата, вы должны теперь использовать:
df %>% distinct(x, y, .keep_all = TRUE)
Ответ 3
В целях полноты работы также работает:
df %>% group_by(x) %>% filter (! duplicated(y))
Тем не менее, я предпочитаю решение с помощью distinct
, и я подозреваю, что он быстрее.
Ответ 4
При выборе столбцов в R для уменьшенного набора данных вы часто можете получить дубликаты.
Эти две строки дают одинаковый результат. Каждый выводит уникальный набор данных только с двумя выбранными столбцами:
distinct(mtcars, cyl, hp);
summarise(group_by(mtcars, cyl, hp));
Ответ 5
В большинстве случаев лучшим решением является использование Different distinct()
от dplyr, как уже было предложено.
Однако здесь есть другой подход, который использует функцию slice()
из dplyr.
# Generate fake data for the example
library(dplyr)
set.seed(123)
df <- data.frame(
x = sample(0:1, 10, replace = T),
y = sample(0:1, 10, replace = T),
z = 1:10
)
# In each group of rows formed by combinations of x and y
# retain only the first row
df %>%
group_by(x, y) %>%
slice(1)
Отличие от использования функции Different distinct()
Преимущество этого решения заключается в том, что оно делает явным то, какие строки сохраняются в исходном кадре данных, и оно может прекрасно сочетаться с функциейrange arrange()
.
Допустим, у вас есть данные о продажах клиентов, и вы хотите сохранить одну запись на каждого клиента, и вы хотите, чтобы эта запись была той из их последней покупки. Тогда вы могли бы написать:
customer_purchase_data %>%
arrange(desc(Purchase_Date)) %>%
group_by(Customer_ID) %>%
slice(1)
Ответ 6
Если вы хотите найти дублирующиеся строки, вы можете использовать find_duplicates
из hablar
:
library(dplyr)
library(hablar)
df <- tibble(a = c(1, 2, 2, 4),
b = c(5, 2, 2, 8))
df %>% find_duplicates()