我想检查矩阵或数据帧中的哪些行是重复的,如何找到它?
我们希望删除重复的行。重复行是指通过忽略列1和列2的排序而具有相同值的行。
例如,对于以下矩阵:
Col1 Col2 database
A B IntAct
A B Bind
B A BioGrid我只想要其中一行。
Col1 Col2 database
A B IntAct发布于 2016-04-29 15:15:59
下面是使用pmax/pmin的另一种选择
library(data.table)
setDT(df1)[!duplicated(pmin(Col1, Col2), pmax(Col1, Col2))]
# Col1 Col2 database
#1: A B IntAct使用更大的数据进行基准测试:
# dummy data
set.seed(123)
df <- data.frame(Col1 = sample(c("A", "B", "C"), 1000, replace = TRUE),
Col2 = sample(c("A", "B", "C"), 1000, replace = TRUE),
database = sample(c("IntAct", "Bind", "BioGrid"), 1000,
replace = TRUE), stringsAsFactors = FALSE)
# benchmark
microbenchmark::microbenchmark(
t = df[ !duplicated(t(apply(df[, 1:2], 1, sort))), ] ,
paste = df[ !duplicated(apply(df[, 1:2], 1,
function(i)paste(sort(i), collapse = ","))), ],
pmin = df[ !duplicated(cbind(pmin(df[, 1], df[, 2]), pmax(df[, 1], df[, 2]))), ],
times = 1000)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# t 33.49008 36.337253 38.374825 37.420015 39.610627 153.89251 1000 b
# paste 33.24177 36.102055 38.079015 37.330498 39.465803 151.43734 1000 b
# pmin 2.59116 2.790864 3.034999 2.910316 3.137389 11.99905 1000 a 发布于 2016-04-29 15:32:22
使用sqldf的冗长替代方案
第一行
我们创建一个id列来获取第一次出现的内容。
library(sqldf)
df$id <- seq.int(nrow(df))
sqldf("select col1, col2, database, min(id) id
from (select col1, col2, database, id from df where col1 <= col2
union all
select col2 col1, col1 col2, database, id from df where col1 > col2)
group by col1, col2")输出:
col1 col2 database id
1 A B IntAct 1最后一行(本例中为第三行)
G. Grothendieck提出的更简洁的选项
sqldf("select col1, col2, database
from (select col1, col2, database from df where col1 <= col2
union all
select col2 col1, col1 col2, database from df where col1 > col2)
group by col1, col2")输出:
col1 col2 database
1 A B BioGrid发布于 2016-04-29 13:25:47
d[!(duplicated(d[,1:2]) | rev(duplicated(d[rev(rownames(d)), 1:2]))),]
Col1 Col2 database
1 A B IntActduplicated显示与索引较低的行匹配的行。这还不够,但是将它应用于数据帧上,无论是从上到下还是从下到上,都能得到您想要的结果。
https://stackoverflow.com/questions/36930063
复制相似问题