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.large
data.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