如何有效地匹配/分组重复行的索引?
假设我有这个数据集:
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) )
我怎样才能有效地做到这一点?
这是使用"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
.
我们可以用dplyr
.使用与@ AnandaMahto的帖子类似的方法,我们创建一个行索引列名称(add_rownames(
),按所有列分组,我们filter
将每个组中的行数大于1的数据集,summarise
将"rowname"创建为a 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"