2017-04-10 4 views
0

Ich schreibe ein einfaches Programm, das eine .tsv-Datei in mehrere CSV-Dateien analysieren sollte. Das Problem ist, dass es so schrecklich lange gedauert hat (ich denke 9 Minuten auf ~ 50k Zeilen ist eine schreckliche Leistung). Kann mir jemand meinen Code ansehen und mir sagen, was mache ich falsch?R Iterieren durch 50k Datenframe dauerte lange

Ich habe eine Tabelle, die name of participant, name of media, timestamp enthält, und einige Koordinatendaten. In meinen Daten kann es einen oder mehrere Teilnehmer geben und jeder Teilnehmer hat mit 2 Mediendateien gearbeitet. Und ich möchte csv-Datei für jeden von media files konkreten Teilnehmer mit erstellen erstellen.

Zum Beispiel habe ich zwei Teilnehmer P1 und P2 und jeder arbeitete auf Mediendateien M1 und M2. So möchte ich P1_M1.csv, P1_M2.csv, P2_M1.csv, P2_M2.csv erstellen.

Daten sieht wie folgt aus:

P1 | M1 | data... 
P1 | M1 | data... 
... 
P1 | M2 | data... 
... 
P2 | m1 | data... 
... 
... 

Hier ist mein Code:

data = read.table("./data.tsv", header = T, sep = "\t", stringsAsFactors = F) # load data from tsv 

# function for creating csv file 
writeData = function(filename, d){ 
    filename = paste("./", filename, ".csv", sep = "") 
    write.csv(d, file = filename, row.names = F) 
} 

# initialize auxiliary variables 
participantName = "" 
mediaName = "" 
# initialize empty dataframe 
subdata <- data.frame(TimeStamp = numeric(), GazeLeftX = integer(), GazeLeftY = integer(), GazeRightX = integer(), GazeRightY = integer()) 

# for each row in original data... 
for(r in 1:nrow(data)) 
{ 
    # check if last participant is same as participant on actual row 
    if(participantName != data[r, 'ParticipantName']){ 
    # check if last participant is not empty (like no participant was processed yet) 
    if(participantName != ""){ 
     # if it is not than participant and also his work on media file ended so write data to csv 
     writeData(filename = paste(participantName,"_",mediaName, sep = ""), d = subdata) 
     # empty auxiliary dataframe and also mediaName 
     subdata = subdata[0,] 
     mediaName = "" 
    } 
    # we detected new participant so record it into last participant variable 
    participantName = data[r, 'ParticipantName'] 
    } 
    # do same checks for media file because there can also change only mediafile and participant can be the same 
    if(mediaName != data[r, 'MediaName']){ 
    if(mediaName != ""){ 
     writeData(filename = paste(participantName,"_",mediaName, sep = ""), d = subdata) 
     subdata = subdata[0,] 
    } 
    mediaName = data[r, 'MediaName'] 
    } 
    # in every iteration append actual row into auxilliary dataframe 
    subdata = rbind(subdata, 
        TimeStamp = data.frame(data[r, 'EyeTrackerTimestamp'], 
        GazeLeftX = data[r, 'GazeLeftX'], 
        GazeLeftY = data[r, 'GazeLeftY'], 
        GazeRightX = data[r, 'GazeRightX'], 
        GazeRightY = data[r, 'GazeRightY'])) 
} 
# if there are any data left in auxiliary dataframe, save it to csv 
if(nrow(subdata) != 0){ 
    writeData(filename = paste(participantName,"_",mediaName, sep = ""), d = subdata) 
} 
+3

Siehe '? Split'. Probieren Sie zum Beispiel 'split (Daten, Daten [, c (" ParticipantName "," MediaName ")])'. – nicola

+0

@nicola vielen Dank. Dies ist perfekt. bitte kannst du eine antwort schreiben, wenn du willst und ich werde es als lösung markieren. Jetzt habe ich nur ein Problem, dass mein Code nur eine CSV-Datei erstellt, aber es ist wahrscheinlich nur ein dummer Fehler in meinem Code :) – Gondil

Antwort

1

Sie suchen ?split suchen. Versuchen Sie zum Beispiel:

split(data,data[,c("ParticipantName","MediaName")],drop=TRUE) 

, die ein list enthält ein data.frame für jedes ParticipantName schaffen - MediaName Paar. Wenn Sie jeden Datenrahmen auf eine andere Datei schreiben möchten, können Sie versuchen, so etwas wie:

res<-split(data,data[,c("ParticipantName","MediaName")],drop=TRUE) 
Map(writeData,names(res),res) 

wo writeData ist die Funktion, die Sie definiert.