我在数据框中有两列,并且我能够使用unique( )
删除所有重复的行 - 这是一种享受。
但是现在我想删除的行是值是相同的,无论它们在哪一列。比如......
data1 data2
data3 data2
data2 data1
data2 data3
应简化为
data1 data2
data3 data2
因为第3行和第4行与1和2相同。
有什么想法吗?
答案 0 :(得分:3)
首先按列排序(使用apply
和sort
),然后使用unique
:
dat <- read.table(text="
data1 data2
data3 data2
data2 data1
data2 data3")
unique(t(apply(dat, 1, sort)))
[,1] [,2]
[1,] "data1" "data2"
[2,] "data2" "data3"
答案 1 :(得分:0)
我创建了一个新列,其中包含您已粘贴在一起的已排序列,然后是unique()。
# create some dummy data
adf <- data.frame(colA=c('data1', 'data3', 'data2', 'data2'),
colB=c('data2', 'data2', 'data1', 'data3'), stringsAsFactors=FALSE)
# function to fix up this data...
# can't see a way of avoiding the loop at the moment, but I'm sure somebody will!
fixit <- function(adf) {
nc <- vector(mode='character', length=nrow(adf))
for (i in 1:nrow(adf)) {
nc[i] <- paste(sort(c(adf[i,1], adf[i,2])), collapse='')
}
adf[!duplicated(nc),]
}
fixit(adf)
在大数据框架上使用循环会很慢,但可以通过使用
来加速library(compiler)
faster.fixit <- cmpfun(fixit)
faster.fixit(adf)
我知道这有点偏离主题,但有趣的是当我对这个循环函数进行基准测试时,字节编译版本的速度只提高了约5%
# create a bigger test data.frame
N <- 10
adf.bigger <- data.frame(colA=rep(adf$colA, N), colB=rep(adf$colB, N),
stringsAsFactors=FALSE)
N <- 1000
adf.biggest <- data.frame(colA=rep(adf$colA, N), colB=rep(adf$colB, N),
stringsAsFactors=FALSE)
library(microbenchmark)
microbenchmark(fixit(adf), faster.fixit(adf), times=1000L)
microbenchmark(fixit(adf.bigger), faster.fixit(adf.bigger), times=1000L)
microbenchmark(fixit(adf.biggest), faster.fixit(adf.biggest), times=100L)