我有一个数据框,其尺寸为 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,]}}
这又太慢了! 有没有更快的方法来查找数据帧的一列中的唯一值?
data[!duplicated(data$Seq), ]
应该可以解决问题。
library(dplyr)
data %>% distinct
应该是值得的,特别是如果你的数据对于你的机器来说太大了。
为了最快,你可以尝试:
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::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
我的版本有几栏。这是我发现的最快的方法。
uniq_df <- df %>%
collapse::funique(., cols = c('col1', 'col2'))