如何加速“唯一”数据框的搜索

4

我有一个数据框,它有2377426行2列,大致看起来像这样:

                   Name                                            Seq
428293 ENSE00001892940:ENSE00001929862 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
431857 ENSE00001892940:ENSE00001883352 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGAAGTAAATGAGCTGATGGAAGAGC
432253 ENSE00001892940:ENSE00003623668 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGAAGTAAATGAGCTGATGGAAGAGC
436213 ENSE00001892940:ENSE00003534967 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGAAGTAAATGAGCTGATGGAAGAGC
429778 ENSE00001892940:ENSE00002409454 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAGCTGGGAACCTTTGCTCAAAGCTCC
431263 ENSE00001892940:ENSE00001834214 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAGCTGGGAACCTTTGCTCAAAGCTCC

第一列(名称)中的所有值都是唯一的,但在“Seq”列中有许多重复项。我需要一个数据框,其中仅包含唯一序列和名称。我尝试过使用unique函数,但速度太慢了。我还尝试过对数据库进行排序,并使用以下代码:

dat_sorted = data[order(data$Seq),]
    m = dat_sorted[1,]
    x =1;for(i in 1:length(dat_sorted[,1])){if(dat_sorted[i,2]!=m[x,2]){x=x+1;m[x,]=dat_sorted[i,]}}

再次强调,这样太慢了!有没有更快的方法来查找数据框中一列中的唯一值?


你知道在R中有一个?unique函数吗?还可以查看?duplicated - talat
@beginneR,我想他提到了他尝试过“unique”。 - David Arenburg
unique 应该非常高效,可以尝试使用 dplyrdata.table 中的 distinct 或者是 unique。例如:library(data.table); unique(setDT(data), by = "Seq") 或者是 setDT(data)[!duplicated(Seq)] - David Arenburg
dplyr版本将是data %>% group_by(Seq) %>% distinct()。还可以参考类似的问题http://stackoverflow.com/questions/27255065/removing-duplicates-for-each-id/27255441#27255441。 - talat
就此而言,我刚刚在一个大约有310万行的数据框上比较了uniquedplyr::distinct,结果distinct要快得多,仅需几分之一秒的时间。 - mal
4个回答

5
data[!duplicated(data$Seq), ]

应该能解决问题。

那行末的 , 是用来干嘛的?它代表什么意思? - Przemyslaw Remin
1
!duplicated非常慢;事实上,即使在仅有1000万行数据集的情况下,使用它来处理2列数据也需要很长时间。kit::funique是更好的选择。 - ColorStatistics

4
library(dplyr)
data %>% distinct

如果你的数据太大,机器跑不动,那么这个工具一定值得一试。


3

对于速度最快的选项,您可以尝试:

data[!kit::fduplicated(data$Seq), ]

以下是直接从文档中获取的一些基准测试结果:
x = sample(c(1:10,NA_integer_),1e8,TRUE) # 382 Mb
microbenchmark::microbenchmark(
  duplicated(x),
  fduplicated(x),
  times = 5L
)
# Unit: seconds
#           expr  min   lq  mean  median   uq   max neval
# duplicated(x)  2.21 2.21  2.48    2.21 2.22  3.55     5
# fduplicated(x) 0.38 0.39  0.45    0.48 0.49  0.50     5

kit 还有一个 funique 函数。


kit::funique是正确的选择;!duplicated非常慢(即使对于非列表和原子向量也是如此)。 - ColorStatistics

0

kit::fduplicated 看起来在具有许多唯一行(少数重复)的数据框中略微占优势,而 dplyr::distinct 在具有许多重复行(少数唯一行)的数据框中似乎更有效:

# Make this example reproducible
set.seed(1)
n_samples <- 1e7

# Many unique rows case: Create a data frame with random integers between 1 and 100
df <- as.data.frame(matrix(round(runif(n=n_samples, min=1, max=1000), 0), nrow=n_samples/2))
names(df) <- c('A', 'B')

microbenchmark::microbenchmark(
  un_1 <- df[!base::duplicated(df), ],
  un_2 <- df[!kit::fduplicated(df), ],
  un_3 <- dplyr::distinct(df),
  times = 5L
)

# Unit: milliseconds
#                                expr       min         lq       mean     median         uq        max neval
# un_1 <- df[!base::duplicated(df), ] 9817.6096 10173.5799 10721.0293 10772.2749 11073.4896 11768.1927     5
# un_2 <- df[!kit::fduplicated(df), ]  558.9923   618.1214   673.6863   628.9305   671.2307   891.1565     5
#         un_3 <- dplyr::distinct(df)  596.9396   640.1986   680.0212   643.6371   674.5296   844.8010     5


# Many repeated rows case: Create a data frame with random integers between 1 and 10
df <- as.data.frame(matrix(round(runif(n=n_samples, min=1, max=10), 0), nrow=n_samples/2))
names(df) <- c('A', 'B')

microbenchmark::microbenchmark(
  un_1 <- df[!base::duplicated(df), ],
  un_2 <- df[!kit::fduplicated(df), ],
  un_3 <- dplyr::distinct(df),
  times = 5L
)

#Unit: milliseconds
#                                 expr       min        lq     mean    median        uq       max neval
#  un_1 <- df[!base::duplicated(df), ] 8282.4409 8439.2752 8550.715 8457.0352 8704.7729 8870.0511     5
#  un_2 <- df[!kit::fduplicated(df), ]  130.8126  136.0880  244.323  168.6322  221.6255  564.4568     5
#          un_3 <- dplyr::distinct(df)  148.4684  160.8196  162.815  165.0068  169.5027  170.2775     5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接