有可能改善这种循环吗?

时间:2017-06-17 10:11:04

标签: r loops

我一直在阅读如何在R中改进代码,看一下这里的一些答案,并阅读一些 R inferno 文档。现在我遇到了这个问题,我创建的循环似乎永远需要(15小时计算)。

k <- NROW(unique(df$EndStation.Id))
l <- NROW(unique(df$StartStation.Id))
m1 <- as.matrix(df[,c("Duration","StartStation.Id","EndStation.Id")])
g <- function(m){
    for (i in 1:l){
        for (j in 1:k){
            duration <- m[(m[,2]==i & m[,3]==j),1]
            if (NROW(duration)<=1) {
                m[(m[,2]==i & m[,3]==j),1] <- NA
                next
        }
        duration <- duration/median(duration)
        m[(m[,2]==i & m[,3]==j),1] <-  duration
        }
    }
return(m)
}

answer <- g(m1)

站的数量(开始和结束)都是750,持续时间矢量大小可以从1或2到80变化很多。这个循环是不可能的,还是我应该放弃并尝试访问更快的计算机。

祝你好运, 费尔南多

2 个答案:

答案 0 :(得分:0)

代码有点难以阅读,但我认为这就是你想要做的事情:

library(data.table)
## generate a data table
dt <- setDT(df[,c("Duration","StartStation.Id","EndStation.Id")])
## calculate the duration
dt[, Duration := Duration / median(Duration), by = .(StartStation.Id, EndStation.Id)]
## replace the result with NA when the vector length == 1
dt[, N := .N, by = .(StartStation.Id, EndStation.Id)][
    N == 1, Duration := NA
    ][, N := NULL]

答案 1 :(得分:0)

如果我正确理解您的功能,您希望将两个电台之间的持续时间除以中位数持续时间,如果该电台对只有一个条目设置为NA

这是一个基础解决方案(它有点笨重,我还没有喝完第一杯咖啡):

##Some sample data
df <- data.frame(StartStation.Id=sample(LETTERS[1:10], 100, replace =T),
                 EndStation.Id=sample(LETTERS[11:20], 100, replace =T),
                 Duration=runif(100, 0.1,100))
    res <- tapply(df$Duration, paste0(df$StartStation.Id, df$EndStation.Id), function(x) x/median(x))
    res <- data.frame(StartStation.Id=sapply(strsplit(rep(names(res), sapply(res, length)), ""), "[", 1),
                      EndStation.Id=sapply(strsplit(rep(names(res), sapply(res, length)), ""), "[", 2),
                      durn=unlist(res))
res[res$durn==1,] <- NA