2014-11-27 7 views
2

Следующая проблема:Удалить дублирующиеся строки в ряд

У меня есть кадр данных data1 с переменной включая несколько записей:

data1 <- data.frame(v1 = c("test, test, bird", "bird, bird", "car")) 

Теперь я хочу, чтобы удалить дубликаты записей в каждой строке. Результат должен выглядеть следующим образом:

data1.final <- data.frame(v1 = c("test, bird", "bird", "car")) 

Я попытался это:

data1$ID <- 1:nrow(data1) 
data1$v1 <- as.character(data1$v1) 

data1 <- split(data1, data1$ID) 
reduce.words <- function(x) { 
    d <- unlist(strsplit(x$v1, split=" ")) 
    d <- paste(d[-which(duplicated(d))], collapse = ' ') 
    x$v1 <- d 
    return(x) 
} 
data1 <- lapply(data1, reduce.words) 
data1 <- as.data.frame(do.call(rbind, data1)) 

Однако это дает пустые строки, кроме первой. У кого-нибудь есть идея решить эту проблему?

ответ

5

У вас, кажется, довольно сложный рабочий процесс. Как насчет просто создать простую функцию, которая работает над строками

reduce_row = function(i) { 
    split = strsplit(i, split=", ")[[1]] 
    paste(unique(split), collapse = ", ") 
} 

, а затем с помощью apply

data1$v2 = apply(data1, 1, reduce_row) 

получить

R> data1 
       v1   v2 
1 test, test, bird test, bird 
2  bird, bird  bird 
3    car  car 
3

Другой вариант использования cSplit от splitstackshape

library(splitstackshape) 
cSplit(cbind(data1, indx=1:nrow(data1)), 'v1', ', ', 'long')[, 
     toString(v1[!duplicated(v1)]), 
            by=indx][,indx:=NULL][] 
    #   V1 
    #1: test, bird 
    #2:  bird 
    #3:  car 

Или, как @Ananda Mahto упоминается в комментариях

unique(cSplit(as.data.table(data1, keep.rownames = TRUE), 
        "v1", ",", "long"))[, toString(v1), by = rn] 

# rn   V1 
#1: 1 test, bird 
#2: 2  bird 
#3: 3  car 
+0

работает отлично, как хорошо! спасибо! – OAM

+0

(+1). Мои личные предпочтения (не уверен, что это более эффективно или нет) - использовать 'keep.rownames' и' unique', поэтому что-то вроде 'unique (cSplit (as.data.table (data1, keep.rownames = TRUE) «v1», «,», «long»)) [, toString (v1), by = rn] '. – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto Спасибо, я не думал о 'keep.rownames' Это хороший вариант. – akrun

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