R中的唯一对,忽略顺序
假设我有这样一个数据帧:R中的唯一对,忽略顺序,r,R,假设我有这样一个数据帧: dat<-data.frame(c("a", "b", "c"), c("b", "a", "d"), stringsAsFactors=F) colnames(dat)<-c("V1", "V2") dat # V1 V2 # 1 a b # 2 b a # 3 c d 执行此操作的最有效方法是什么?您可以使用apply()对每行进行排序,强制返回到data.frame(因为apply()将返回一个矩阵),然后通过uniq
dat<-data.frame(c("a", "b", "c"), c("b", "a", "d"), stringsAsFactors=F)
colnames(dat)<-c("V1", "V2")
dat
# V1 V2
# 1 a b
# 2 b a
# 3 c d
执行此操作的最有效方法是什么?您可以使用apply()
对每行进行排序,强制返回到data.frame
(因为apply()
将返回一个矩阵),然后通过unique()
运行它:
一个选项(由@bgoldst回答)是使用apply
分别对每一行进行排序。但是,对于在列上操作的大数据帧,我们可以使用对pmin
和pmax
的单个调用来获得更好的性能,而不是在行上使用对sort
的多次调用:
# Make a larger data frame by sampling
set.seed(144)
dat.large <- dat[sample(nrow(dat), 10000, replace=T),]
# Row-wise and column-wise computations
rowwise <- function(dat) unique(t(apply(dat, 1, sort)))
colwise <- function(dat) unique(cbind(pmin(dat[,1], dat[,2]), pmax(dat[,1], dat[,2])))
all.equal(unname(rowwise(dat.large)), unname(colwise(dat.large)))
# [1] TRUE
# Compare performance
library(microbenchmark)
microbenchmark(rowwise(dat.large), colwise(dat.large))
# Unit: milliseconds
# expr min lq mean median uq max neval
# rowwise(dat.large) 465.45604 523.49464 564.91541 559.14461 595.58961 805.7982 100
# colwise(dat.large) 33.69199 42.91692 50.87839 47.70415 53.06705 122.4459 100
#通过采样生成更大的数据帧
种子集(144)
dat.largedata.frame(c('b','a','c'),c('a','d','c'))
的输出将与输入相同,因为没有重复匹配的pairsAh,现在我得到了它。谢谢。它能为康拉德的例子提供正确的答案吗,即数据帧(c('b','a','c'),c('a','d','c'))
?@MaratTalipov是的,我刚刚检查过,它产生了正确的答案
dat <- data.frame(c('a','b','c'), c('b','a','d'), stringsAsFactors=F );
colnames(dat) <- c('V1','V2');
x <- unique(as.data.frame(t(apply(dat, 1, sort ))));
rownames(x) <- 1:nrow(x);
x;
V1 V2
1 a b
2 c d
# Make a larger data frame by sampling
set.seed(144)
dat.large <- dat[sample(nrow(dat), 10000, replace=T),]
# Row-wise and column-wise computations
rowwise <- function(dat) unique(t(apply(dat, 1, sort)))
colwise <- function(dat) unique(cbind(pmin(dat[,1], dat[,2]), pmax(dat[,1], dat[,2])))
all.equal(unname(rowwise(dat.large)), unname(colwise(dat.large)))
# [1] TRUE
# Compare performance
library(microbenchmark)
microbenchmark(rowwise(dat.large), colwise(dat.large))
# Unit: milliseconds
# expr min lq mean median uq max neval
# rowwise(dat.large) 465.45604 523.49464 564.91541 559.14461 595.58961 805.7982 100
# colwise(dat.large) 33.69199 42.91692 50.87839 47.70415 53.06705 122.4459 100