2012-06-16 2 views
1

У меня есть два столбца в кадре данных, и я смог удалить все повторяющиеся строки с помощью unique() - Работает с удовольствием.Удалить строки с повторяющимися значениями в разных столбцах

Но теперь я хочу, чтобы удалить строки были значения одинаковы, независимо от того, какой столбец они находятся. Как ...

data1 data2 
data3 data2 
data2 data1 
data2 data3 

Должно быть упрощена

data1 data2 
data3 data2 

поскольку строки 3 и 4 являются такими же, как 1 и 2.

Любые идеи?

ответ

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" 
+0

+1 @Andrie для чистого использования. Интересно, что моя скомпилированная функция занимает около 439 микросекунд, а приложение занимает 515 микросекунд для небольшой таблицы с четырьмя строками. Однако для таблицы 4000 строк это наоборот - 3,45 мс против 2,92 мс. В целом разница меньше, чем я ожидал. – Sean

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) 

Имея цикл будет медленным на большом data.frame, но он может быть ускорен с помощью

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) 
+1

Что такое 'comfun'? Должно ли это быть 'cmpfun'? – GSee

+0

@ GПожалуйста, вы абсолютно правы - сделанные изменения – Sean

Смежные вопросы