说我有这样的数据框:
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
我想要做的是,每行成对,生成所有唯一对,忽略顺序。所以我的输出就像是
unique_pairs(dat$V1, dat$V2)
# Output
# V1 V2
# 1 a b
# 2 c d
最有效的方法是什么?
答案 0 :(得分:3)
一个选项(由@bgoldst回答)是用apply
分别对每一行进行排序。但是,对于使用pmin
和pmax
的单个调用,而不是使用对sort
的多次调用的行,我们可以在列上运行的大型数据帧中获得更好的性能:< / p>
# 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
正如您所看到的,对于10000行输入,列式运算速度提高了大约10倍,显示了在R中计算时矢量化的强大功能。显然,从500 ms到50 ms的加速可能不是什么大问题,但是如果您正在处理大型数据集,那么矢量化方法可能更可取。
答案 1 :(得分:2)
您可以使用apply()
对每一行进行排序,然后强制回data.frame
(因为apply()
将返回一个矩阵),然后通过unique()
运行:
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