2015-06-16 18 views
6

Mam listę wektorów, powiedzieć:usunąć duplikaty i małe wektory z listy

li <- list(c(1, 2, 3), 
      c(1, 2, 3, 4), 
      c(2, 3, 4), 
      c(5, 6, 7, 8, 9, 10, 11, 12), 
      numeric(0), 
      c(5, 6, 7, 8, 9, 10, 11, 12, 13) 
      ) 

I chciałbym, aby usunąć wszystkie wektory, które są już zawarte w innych (większy lub równy), jak również wszystkie puste wektory

w tym przypadku, chciałbym być już tylko liście

1 2 3 4 
5 6 7 8 9 10 11 12 13 

Czy istnieje funkcja użyteczna dla osiągnięcia tego celu?

Dzięki z góry

+0

Spójrz na [ta odpowiedź] (http://stackoverflow.com/a/27521122/3521006) - myślę, że to, co szukasz (wystarczy umieścić swoje wektorów na liście) –

+0

Właściwie to, co chciałbym osiągnąć, to coś innego: po pierwsze pozbyłbym się pustych wektorów. Po drugie, chciałbym usunąć wektory już zawarte w innych ... – Ruggero

Odpowiedz

2

Najpierw należy posortować listę według długości wektora, tak aby w pętli wycięcia było zagwarantowane, że każdy wektor o niższym indeksie jest krótszy niż każdy wektor o wyższym indeksie, więc wystarczy tylko jednokierunkowy setdiff().

l <- list(1:3, 1:4, 2:4, 5:12, double(), 5:13); 
ls <- l[order(sapply(l,length))]; 
i <- 1; while (i <= length(ls)-1) if (length(ls[[i]]) == 0 || any(sapply((i+1):length(ls),function(i2) length(setdiff(ls[[i]],ls[[i2]]))) == 0)) ls[[i]] <- NULL else i <- i+1; 
ls; 
## [[1]] 
## [1] 1 2 3 4 
## 
## [[2]] 
## [1] 5 6 7 8 9 10 11 12 13 

Oto niewielkie alternatywą wymiany any(sapply(...)) z drugiej pętli while. Zaletą jest to, że pętla while może przedwcześnie się przedwcześnie złamać, jeśli znajdzie resztę na pozostałej liście.

l <- list(1:3, 1:4, 2:4, 5:12, double(), 5:13); 
ls <- l[order(sapply(l,length))]; 
i <- 1; while (i <= length(ls)-1) if (length(ls[[i]]) == 0 || { j <- i+1; res <- F; while (j <= length(ls)) if (length(setdiff(ls[[i]],ls[[j]])) == 0) { res <- T; break; } else j <- j+1; res; }) ls[[i]] <- NULL else i <- i+1; 
ls; 
## [[1]] 
## [1] 1 2 3 4 
## 
## [[2]] 
## [1] 5 6 7 8 9 10 11 12 13 
0

x jest zawarty w Y jeśli

length(setdiff(x, y)) == 0 

Można zastosować go do każdej pary wektorów wykorzystujących funkcje jak expand.grid lub combn.

+0

Czy to podejście nie byłoby niepotrzebnie powtarzalne? Jeśli wypróbujesz wszystkie kombinacje, niż kilkakrotnie sprawdzasz element wymienny, musisz zrobić to tylko raz. – Molx

Powiązane problemy