2017-01-20 1 views
1

Я хочу удалить строки на основе повторяющегося элемента в первом столбце, но также хочу сохранить второй столбец. Любое из значений, связанных с повторяющимся элементом во втором столбце, которое я могу использовать.Храните повторяющийся элемент один раз и весь кадр данных в r

Вход:

df = data.frame(col1 = c("a", "a", "a", "b", "b", "c"), col2 = 1:6) 

Ожидаемый результат:

col1 col2 
a 1 
b 4 

или

col1 col2 
    a 2 
    b 5 

т.д.

До сих пор пытались с ниже команды, но не держать весь dataframe :

df[(duplicated(df$col1)),] 

ответ

2

С dplyr мы можем group_bycol1, а затем включить только те группы, которые встречаются более чем один раз и получить первую строку по группам с slice

library(dplyr) 
df %>% 
    group_by(col1) %>% 
    filter(n() > 1) %>% 
    slice(1) 

# col1 col2 
# <fctr> <int> 
#1 a  1 
#2 b  4 

Чтобы получить вторую строку из каждой группы мы можем просто

df %>% 
    group_by(col1) %>% 
    filter(n() > 1) %>% 
    slice(2) 

# col1 col2 
# <fctr> <int> 
#1  a  2 
#2  b  5 

Мы можем также использовать функцию row_number в dplyr

df %>% 
    group_by(col1) %>% 
    filter(n() > 1) %>% 
    filter(row_number() == 1) 
2

следующие должны делать то, что вы хотите:

> df = data.frame(col1 = c("a", "a", "a", "b", "b", "c"), col2 = 1:6) 
> t <- table(df[,1]) 
> df[match(names(t[t>1]),df[,1]),] 
    col1 col2 
1 a 1 
4 b 4 

Краткое объяснение: table(...) подсчитывает количество раз, каждый элемент apears в первом столбце. names(t[t>1]) выбирает только те, которые появляются не менее двух раз, и match(...) дает (первый) индекс указанных элементов. Наконец, выбираются строки, соответствующие этим индексам.

+0

Спасибо @ Jonathan, я тоже не хочу 6-й ряд. Посмотрите мой ожидаемый результат. –

+0

Значит, вам нужны только те, которые повторяются два или более раза? –

+0

Да, точно. @Jonathan –

0

Мы можем сделать это с помощью data.table. Преобразование «data.frame» в «data.table» (setDT(df)), сгруппированные по «col1», if число строк больше 1, получаем первую строку

library(data.table) 
setDT(df)[, if(.N>1) head(.SD, 1) , col1] 
# col1 col2 
#1: a 1 
#2: b 4 

Если нам нужно второе значение

setDT(df)[, if(.N>1) .SD[2] , col1] 
# col1 col2 
#1: a 2 
#2: b 5 

Или с помощью dplyr

library(dplyr) 
df %>% 
    group_by(col1) %>% 
    filter(n()>1 & row_number()==1) 
# col1 col2 
# <fctr> <int> 
#1  a  1 
#2  b  4