2015-12-27 9 views
7

Attualmente sto lavorando con i dati di tracciamento degli occhi, quindi ho un set di dati ENORME (penso a milioni di righe) e vorrei un modo veloce per eseguire questa operazione. Ecco una versione semplificata di esso.modo rapido ed efficiente per eseguire il looping su milioni di righe e colonne corrispondenti

I dati indicano dove l'occhio guarda ogni punto temporale e per ogni file che stiamo guardando. X1, Y1 alle coordinate del punto che stiamo guardando. Ci sono più punti di tempo per ogni file (che rappresenta l'occhio che guarda la diversa posizione nel file nel tempo).

Filename Time X1 Y1 
    1   1  10 10 
    1   2  12 10 

Ho anche un file di dove si trovano gli elementi per ogni nome di file. Ogni file contiene (in questo caso semplificato) due oggetti. X1, Y1 sono le coordinate in basso a sinistra e X2, Y2 sono in alto a destra. Potete immaginarlo come dando il riquadro di delimitazione in cui l'elemento si trova in ogni file. Per esempio.

Filename Item X1 Y1 X2 Y2 
    1   Dog 11 10 20 20 

Quello che mi piacerebbe fare è aggiungere un'altra colonna al primo frame di dati che mi ha quale oggetto la persona sta guardando in ogni momento per ogni file dice. Se non guardi nessuno degli oggetti, mi piacerebbe che la colonna dicesse "none". Le cose al confine sono considerate come guardate. Per esempio.

Filename Time X1 Y1 LookingAt 
    1   1  10 10 none 
    1   2  12 11 Dog 

so come fare questo il ciclo for strada, ma ci vuole sempre (e si è schiantato il mio RStudio). Mi chiedo se ci possa essere un modo più veloce, più efficiente che mi manchi.

Ecco il dput per la prima dataframe (Questi contengono più righe che l'esempio ho mostrato sopra):

structure(list(Filename = structure(c(1L, 1L, 1L, 2L, 2L, 3L, 
3L, 3L, 3L), .Label = c("1", "2", "3"), class = "factor"), Time = structure(c(1L, 
2L, 3L, 1L, 2L, 1L, 2L, 4L, 5L), .Label = c("1", "2", "3", "5", 
"6"), class = "factor"), X1 = structure(c(1L, 4L, 3L, 2L, 1L, 
4L, 6L, 5L, 1L), .Label = c("10", "11", "12", "15", "20", "25" 
), class = "factor"), Y1 = structure(c(1L, 5L, 6L, 4L, 1L, 2L, 
3L, 4L, 1L), .Label = c("10", "11", "12", "15", "20", "25"), class = "factor")), .Names = c("Filename", 
"Time", "X1", "Y1"), row.names = c(NA, -9L), class = "data.frame") 

Ed ecco il dput per il secondo:

structure(list(Filename = structure(c(1L, 1L, 2L, 2L), .Label = c("1", 
"3"), class = "factor"), Item = structure(1:4, .Label = c("Cat", 
"Dog", "House", "Mouse"), class = "factor"), X1 = structure(c(2L, 
4L, 3L, 1L), .Label = c("10", "11", "20", "35"), class = "factor"), 
Y1 = structure(c(2L, 4L, 3L, 1L), .Label = c("10", "11", 
"13", "35"), class = "factor"), X2 = structure(c(1L, 3L, 
4L, 2L), .Label = c("10", "11", "20", "35"), class = "factor"), 
Y2 = structure(c(1L, 3L, 4L, 2L), .Label = c("10", "11", 
"13", "35"), class = "factor")), .Names = c("Filename", "Item", 
"X1", "Y1", "X2", "Y2"), row.names = c(NA, -4L), class = "data.frame") 
+2

Date un'occhiata al formato data.table, è molto buono per affrontare questo numero di righe. È quindi possibile creare la nuova colonna per riferimento, che è molto molto veloce – Shape

+2

Nel secondo dput, perché le colonne X1, Y1, X2 e Y2 sono classificate come fattori? Avrebbero più senso come semplici numeri interi o doppi. Inoltre, passando per le etichette dei fattori, le caselle di delimitazione di Cat e Dog non hanno senso. Ad esempio, Cat ha X1 = 11, Y1 = 11, X2 = 10, Y2 = 10. X1, Y1 dovrebbero essere in basso a sinistra e X2, Y2 in alto a destra? – bgoldst

risposta

4

Utilizzando i dati . tabella e i dati di esempio forniti, vorrei avvicinarlo come segue:

# getting the data in the right format 
datcols <- c("X","Y") 
lucols <- c("X1","X2","Y1","Y2") 
setDT(dat)[, (datcols) := lapply(.SD, function(x) as.numeric(as.character(x))), .SDcol = datcols 
      ][, Filename := as.character(Filename)] 
setDT(lu)[, (lucols) := lapply(.SD, function(x) as.numeric(as.character(x))), .SDcol = lucols 
      ][, `:=` (Filename = as.character(Filename), 
        X1 = pmin(X1,X2), X2 = pmax(X1,X2), # make sure that 'X1' is always the lowest value 
        Y1 = pmin(Y1,Y2), Y2 = pmax(Y1,Y2))] # make sure that 'Y1' is always the lowest value 

# matching the 'Items' to the correct rows 
dat[, looked_at := lu$Item[Filename==lu$Filename & 
         between(X, lu$X1, lu$X2) & 
         between(Y, lu$Y1, lu$Y2)], 
    by = .(Filename,Time)] 

che dà:

> dat 
    Filename Time X Y looked_at 
1:  1 1 10 10  Cat 
2:  1 2 15 20  NA 
3:  1 3 12 25  NA 
4:  2 1 11 15  NA 
5:  2 2 10 10  NA 
6:  3 1 15 11  NA 
7:  3 2 25 12  NA 
8:  3 5 20 15  House 
9:  3 6 10 10  Mouse 

dati utilizzati:

dat <- structure(list(Filename = structure(c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L), .Label = c("1", "2", "3"), class = "factor"), 
        Time = structure(c(1L, 2L, 3L, 1L, 2L, 1L, 2L, 4L, 5L), .Label = c("1", "2", "3", "5", "6"), class = "factor"), 
        X = structure(c(1L, 4L, 3L, 2L, 1L, 4L, 6L, 5L, 1L), .Label = c("10", "11", "12", "15", "20", "25"), class = "factor"), 
        Y = structure(c(1L, 5L, 6L, 4L, 1L, 2L, 3L, 4L, 1L), .Label = c("10", "11", "12", "15", "20", "25"), class = "factor")), 
       .Names = c("Filename", "Time", "X", "Y"), row.names = c(NA, -9L), class = "data.frame") 
lu <- structure(list(Filename = structure(c(1L, 1L, 2L, 2L), .Label = c("1", "3"), class = "factor"), 
        Item = structure(1:4, .Label = c("Cat", "Dog", "House", "Mouse"), class = "factor"), 
        X1 = structure(c(2L, 4L, 3L, 1L), .Label = c("10", "11", "20", "35"), class = "factor"), 
        X2 = structure(c(1L, 3L, 4L, 2L), .Label = c("10", "11", "20", "35"), class = "factor"), 
        Y1 = structure(c(2L, 4L, 3L, 1L), .Label = c("10", "11", "13", "35"), class = "factor"), 
        Y2 = structure(c(1L, 3L, 4L, 2L), .Label = c("10", "11", "13", "35"), class = "factor")), 
       .Names = c("Filename", "Item", "X1", "X2", "Y1", "Y2"), row.names = c(NA, -4L), class = "data.frame") 
+1

Grazie, questo funziona benissimo! data.table è davvero molto veloce. (E mi dispiace per l'inconveniente che non ho fornito dati più igienizzati). – pomegranate

Problemi correlati