2011-11-07 12 views

risposta

6

La tua domanda non è del tutto chiara, ma suppongo che tu voglia sottocampionare l'intero frame di dati, mantenendo una riga (scelta casualmente) per "classe duplicata". Qualcosa di simile

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

dovrebbe funzionare (non testati!)

+1

Questa interpretazione della domanda (criptica) dell'OP sembra più probabile della mia, per cui avrei suggerito 'df [esempio (che (df $ X == mioVal), 1),]'. – joran

+1

Grazie ragazzi, sto provando il suggerimento di Ben, Joran, come fare se voglio applicare questo valore a tutti i valori delle colonne perché myVal come suggerito nei tuoi frammenti cambia lungo la mia colonna X, il che significa che ho centinaia di 5 per esempio e centinaia di 8s ecc ecc – Rad

+0

@ La soluzione di Ben Ben lo gestirà; il mio no. Abbiamo interpretato la tua domanda in modo diverso. – joran

6

Il mio primo istinto sarebbe stato qualcosa di simile soluzione elegante di Ben ddply. Tuttavia, sapendo che hai un set di dati così ampio, ci sono sicuramente modi più veloci. Ecco uno che sarà molto più veloce se si hanno molti valori univoci:

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, ] 
} 

simulare alcuni dati (qui con molti valori unici):

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

Confronta i 2 metodi:

> 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

Elegante! Fantastico, grazie Giovanni – Rad