如何加快“独特”数据框搜索速度

问题描述 投票:0回答:5

我有一个数据框,其尺寸为 2377426 行 x 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”列中有许多重复项。 我想要一个仅包含唯一序列和名称的 data.frame 。我尝试过独特,但这太慢了。我还尝试订购数据库并使用以下代码:

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 performance search unique
5个回答
5
投票
data[!duplicated(data$Seq), ]

应该可以解决问题。


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
功能。


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

0
投票

我的版本有几栏。这是我发现的最快的方法。

uniq_df <- df %>%
 collapse::funique(., cols = c('col1', 'col2'))
© www.soinside.com 2019 - 2024. All rights reserved.