【问题标题】:R iterating through 50k dataframe took long遍历 50k 数据帧需要很长时间
【发布时间】:2017-04-10 13:50:13
【问题描述】:

我正在编写一个简单的程序,它应该将一个 .tsv 文件解析为多个 .csv 文件。问题是它花费了非常长的时间(我认为大约 50k 行上的 9 分钟是可怕的性能)。请有人看看我的代码并告诉我我做错了什么?

我有一个包含name of participant、name of media、timestamp 和一些坐标数据的表。在我的数据中,可以有一个或多个参与者,每个参与者都使用 2 个媒体文件。我想为每个media files 具体参与者创建 csv 文件。

例如,我有 2 个参与者 P1 和 P2,每个人都处理媒体文件 M1 和 M2。所以我想创建P1_M1.csv、P1_M2.csv、P2_M1.csv、P2_M2.csv。

数据如下所示:

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

这是我的代码:

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

【问题讨论】:

  • 见?split。例如split(data,data[,c("ParticipantName","MediaName")])。
  • @nicola 非常感谢。太棒了。如果需要,您可以发布答案,我会将其标记为解决方案。现在我只有一个问题,我的代码只创建了一个 csv 文件,但我的代码中可能只是一些愚蠢的错误 :)

标签: r csv parsing dataframe


【解决方案1】:

您正在寻找?split。例如尝试:

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

这将为每个ParticipantName-MediaName 对创建一个list,其中包含一个data.frame。如果您想将每个数据帧写入不同的文件,您可以尝试以下操作:

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

其中writeData 是您定义的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 2017-08-10
    • 2015-03-12
    • 1970-01-01
    • 2020-08-04
    相关资源
    最近更新 更多