如何在R中优化这个循环?

时间:2016-10-31 15:09:58

标签: r

我在函数内部有一个for循环,它对于具有< 10000行的数据帧运行良好,但是随着行数的增加,循环所用的时间呈指数增长。我已阅读有关优化循环的this帖子。虽然,我不知道如何将它应用到我的情况

以下是for循环:

for (i in 1:nrow(data.frame)) {
    event <- as.character(data.frame[i,"Event"])
    if(i < 20) {
        # do nothing
    }
    else {
        # Get the previous 20 rows
        one.sec.interval = data[(i - (20 - 1)):i,]
        #       print(head(one.sec.interval))

        # get the covariance matrix
        cov.matrix <- var(one.sec.interval)

        # get the variance of the features
        variance.of.features <- diag(cov.matrix)

        # reformat the variance vector into data frame for easier manipulation
        variance.of.features <- matrix(variance.of.features,1,length(variance.of.features))
        variance.of.features <- data.frame(variance.of.features)

        # rename the variance column of the features
        colnames(variance.of.features) <- c('Back.Pelvis.Acc.X.sd', 'Back.Pelvis.Acc.Y.sd', 'Back.Pelvis.Acc.Z.sd',
        'Back.Pelvis.Gyro.X.sd', 'Back.Pelvis.Gyro.Y.sd', 'Back.Pelvis.Gyro.Z.sd',
        'Back.Trunk.Acc.X.sd', 'Back.Trunk.Acc.Y.sd', 'Back.Trunk.Acc.Z.sd',
        'Back.Trunk.Gyro.X.sd', 'Back.Trunk.Gyro.Y.sd', 'Back.Trunk.Gyro.Z.sd')

        # create the new feature vector
        new.feature.vector <- cbind(data[i,], variance.of.features)
        new.feature.vector$Event <- event
        one.sec.interval.data[i- (20 - 1),] <- new.feature.vector
    }
}

1 个答案:

答案 0 :(得分:0)

如果你想使用可以工作的矩阵。或者:

第1步:绝对使用data.table包;这是非常快的。 第2步:在循环之前将事件设置为字符。 第3步:如果可能,不要使用if-loops。在这种情况下,只需将i设置为从20到完整列表,而不是检查它是否低于20:

private Queue<string> q = new Queue<string>();
private Task readFilesTask;
public void ReadFiles(string inputDirectory)
{
    var files = Directory.GetFiles(inputDirectory, "*.txt", SearchOption.TopDirectoryOnly);
    foreach (var file in files)
    {
        var textFromFile = File.ReadAllText(file);
        q.Enqueue(textFromFile);
        File.Delete(file);
    }
}

private void start_Click(object sender, EventArgs e)
{
    readFilesTask = Task.Run(() => ReadFiles("//path/to/dir"));
}

private void stop_Click(object sender, EventArgs e)
{    
    readFilesTask.Wait();
    //readFilesTask.Wait(1000); // if you want kill the task after waiting for 1000 milliseconds
    //Enable buttons
}

第4步:您可以提前设置data.table列,并在最后重命名。

library(data.table)
data.table$Event <- as.character(data.table$event)
for (i in 20:nrow(data.table)) {
   ...do stuff...
}

第5步:根据数据结构的不同,这可能无法实现。但您也可以使用doMC包和foreach循环来进行并行处理。这要求每次运行不依赖于来自任何其他运行的数据。不确定这是否适用于你。

- 希望这有帮助!