2011-11-07 13 views

Odpowiedz

6

Twoje pytanie nie jest całkiem jasne, ale zakładam, że chcesz posortować całą ramkę danych, zachowując jeden (losowo wybrany) wiersz na "zduplikowaną klasę". Coś jak

library(plyr) 
subsampled_data <- ddply(mydata,.(X), 
    function(x) { 
      x[sample(nrow(x),size=1),] 
    }) 

powinien działać (nie testowane!)

+1

Ta interpretacja pytania OP (zagadkowego) wydaje się bardziej prawdopodobna niż moja, dla której zamierzałem zasugerować 'df [sample (which (df $ X == myVal), 1),]'. – joran

+1

Dzięki chłopaki, próbuję sugestii Bena, Joran, jak to zrobić, jeśli chcę zastosować to do całej wartości colum, ponieważ myVal zgodnie z sugestiami zawartymi w twoich fragmentach zmienia się wzdłuż mojej kolumny X, co oznacza, że ​​mam na przykład setki 5 i setki 8s etc etc – Rad

+0

@Rad Ben's rozwiązanie to obsłuży; moje nie. Zinterpretowaliśmy twoje pytanie inaczej. – joran

6

Moim pierwszym odruchem byłoby coś eleganckie rozwiązanie Bena ddply. Jednak wiedząc, że masz tak duży zestaw danych, istnieją zdecydowanie szybsze sposoby. Tutaj jest jeden, który będzie wielokrotnie szybciej, jeśli masz wiele unikalnych wartości:

RemoveDups <- function(df, column) { 
    inds = sample(1:nrow(df)) 
    df = df[inds, ] 

    dups = duplicated(df[, column]) 
    df = df[!dups, ] 
    inds = inds[!dups] 

    df[sort(inds, index=T)$ix, ] 
} 

symulować niektóre dane (tutaj z wielu unikalnych wartości):

n.row = 10^6 
n.col = 3 

set.seed(12345) 
data = data.frame(matrix(sample(1000, n.row*n.col, replace=T), nrow=n.row)) 

Porównaj 2 metody:

> system.time(ddply(data, 'X1', function(x) x[sample(nrow(x), size=1), ])) 
    user system elapsed 
    3.264 0.921 4.315 
> system.time(RemoveDups(data, 'X1')) 
    user system elapsed 
    0.375 0.025 0.399 
+0

Elegancki! Wspaniale, dzięki John – Rad

Powiązane problemy