2015-12-16 2 views
15

Как я могу эффективно сопоставлять/группировать индексы дублированных строк?Соответствующие/групповые повторяющиеся строки (индексы)

Допустим, у меня есть этот набор данных:

set.seed(14) 
dat <- data.frame(mtcars[sample(1:5, 14, TRUE), ])[sample.int(14), ] 
rownames(dat) <- NULL 
dat 

##  mpg cyl disp hp drat wt qsec vs am gear carb 
## 1 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 
## 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 
## 3 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 
## 4 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 
## 5 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 
## 6 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 
## 7 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 
## 8 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 
## 9 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 
## 10 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 
## 11 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 
## 12 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 
## 13 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 
## 14 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 

я могу найти все показатели дубликатов (в том числе первого дубликата) с помощью

which_duplicated <- function(dat){ 
    which(duplicated(dat) | duplicated(dat[nrow(dat):1, ])[nrow(dat):1]) 
} 

which_duplicated(dat) 

## [1] 1 2 3 4 5 6 7 8 9 10 11 13 

Но я хочу, чтобы иметь возможность соответствовать те индексы, как показано ниже:

list(
    c(2, 13), 
    c(1, 4, 5, 6, 9), 
    c(3, 7, 8, 10, 11) 
) 

Как я могу сделать это эффективно?

+1

медленно, но 'фильтр (функция (х) длина (х)> 1, в силу (DAT, as.list (DAT), rownames))' – rawr

ответ

14

Вот возможность использования «data.table»:

library(data.table) 
as.data.table(dat)[, c("GRP", "N") := .(.GRP, .N), by = names(dat)][ 
        N > 1, list(list(.I)), by = GRP] 
## GRP    V1 
## 1: 1  1,4,5,6,9 
## 2: 2   2,13 
## 3: 3 3, 7, 8,10,11 

Основная идея заключается в том, чтобы создать столбец, «группа» другие столбцы (с использованием .GRP), а также столбец, который подсчитывает, сколько дубликатов строки (с использованием .N), затем фильтруют все, что имеет более одного дубликата, и помещают столбец «GRP» в list.

9

Мы можем использовать dplyr. Используя аналогичную методологию, такую ​​как @ AnandaMahto, мы создаем имя столбца индекса строки (add_rownames(), группу по всем столбцам, мы располагаем набором данных с количеством строк в каждой группе больше 1, summarise «rowname» до list и выписка эта list колонка.

library(dplyr) 
add_rownames(dat) %>% 
     group_by_(.dots= names(dat)) %>% 
     filter(n()>1) %>% 
     summarise(rn= list(rowname))%>% 
     .$rn 
#[[1]] 
#[1] "3" "7" "8" "10" "11" 

#[[2]] 
#[1] "2" "13" 

#[[3]] 
#[1] "1" "4" "5" "6" "9" 
+1

оба решения отлично (та же логика, что не будет иметь думал о себе) и эффективен. Я заметил решение Ананды с зеленым тиком, поскольку он сначала с логикой. Спасибо +1 –

Смежные вопросы