生成更高效的for循环

生成更高效的for循环,r,performance,for-loop,R,Performance,For Loop,我创建了一个函数,将Cox回归模型应用于测试数据,基于协变量创建生存函数,然后从当前时间开始预测每个测试观察30天的生存概率 下面的示例使用lung数据集,效果非常好。然而,应用到我自己的数据处理时间是乏味的。对于n=60000,我只是在一小时后停止了它,因为它对于我打算使用该程序的目的不实际 看看代码结构,有没有一种明显的方法可以加快速度 require(dplyr, survival, pec) cox_model <- coxph(Surv(time, status) ~ sex,

我创建了一个函数,将Cox回归模型应用于测试数据,基于协变量创建生存函数,然后从当前时间开始预测每个测试观察30天的生存概率

下面的示例使用lung数据集,效果非常好。然而,应用到我自己的数据处理时间是乏味的。对于n=60000,我只是在一小时后停止了它,因为它对于我打算使用该程序的目的不实际

看看代码结构,有没有一种明显的方法可以加快速度

require(dplyr, survival, pec)

cox_model <- coxph(Surv(time, status) ~ sex, data = lung)

surv_preds <- function(model, query) {

  prediction <- vector(mode = "numeric", length = nrow(query))
  time <- 30

  for(i in 1:nrow(query)) {
    prediction[i] <- predictSurvProb(model, newdata = query[i, ], times = query[i, "time"] + time)
  }
  prediction
}

surv_preds(cox_model, lung)
require(dplyr、生存、pec)

cox_模型你不需要一次预测一行。你可以同时做这一切。例如:

cox_model <- coxph(Surv(time, status) ~ sex, data = lung)

surv_preds <- function(model, query) {

  prediction <- vector(mode = "numeric", length = nrow(query))
  time <- 30

  for(i in 1:nrow(query)) {
    prediction[i] <- predictSurvProb(model, newdata = query[i, ], times = query[i, "time"] + time)
  }
  prediction
}

surv_preds2 <- function(model, query) {

time <- 30

prediction <- predictSurvProb(model, newdata = query, times = query[, "time"] + time)
  prediction
}


microbenchmark(surv_preds(cox_model, lung), surv_preds2(cox_model, lung), times=5)

你不需要一次预测一行。你可以同时做这一切。例如:

cox_model <- coxph(Surv(time, status) ~ sex, data = lung)

surv_preds <- function(model, query) {

  prediction <- vector(mode = "numeric", length = nrow(query))
  time <- 30

  for(i in 1:nrow(query)) {
    prediction[i] <- predictSurvProb(model, newdata = query[i, ], times = query[i, "time"] + time)
  }
  prediction
}

surv_preds2 <- function(model, query) {

time <- 30

prediction <- predictSurvProb(model, newdata = query, times = query[, "time"] + time)
  prediction
}


microbenchmark(surv_preds(cox_model, lung), surv_preds2(cox_model, lung), times=5)

除了问题中的软件包之外,另一条路径是来自
purrlyr
by_row
功能

library(purrrlyr)

prediction <- lung %>%
  mutate(time = time + 30) %>%
  by_row(~predictSurvProb(cox_model, newdata = ., times = .$time)) %>%
  .$.out %>%
  unlist
这两种解决方案都可以在我使用的硬件上运行24小时以上。
鉴于此答案似乎不再能解决您的问题,我不熟悉并行处理选项,我很乐意删除此选项,除非有人认为保留此选项很有价值。

除了问题中的包之外,另一个途径是
purrlyr
中的
by_row
函数

library(purrrlyr)

prediction <- lung %>%
  mutate(time = time + 30) %>%
  by_row(~predictSurvProb(cox_model, newdata = ., times = .$time)) %>%
  .$.out %>%
  unlist
这两种解决方案都可以在我使用的硬件上运行24小时以上。
鉴于这个答案似乎不再能解决您的问题,而且我不熟悉并行处理选项,我很乐意将其删除,除非有人认为保存在这里有价值。

已解决!!如果感兴趣,我想发布我使用的解决方案。我设法完全消除了对for循环的需要

predictSurvProb(cox_model, 
                newdata = lung, 
                times = lung[ , "time"] + 30)[1, ]
这给了我所需要的输出。关键是我从结果矩阵中索引第一行及其所有列。该代码使用每个观测值的唯一生存函数估计值,从观测值在曲线上的当前位置预测30天的生存概率


来自@thc的答案实际上最终为我指明了正确的方向

解决了!!如果感兴趣,我想发布我使用的解决方案。我设法完全消除了对for循环的需要

predictSurvProb(cox_model, 
                newdata = lung, 
                times = lung[ , "time"] + 30)[1, ]
这给了我所需要的输出。关键是我从结果矩阵中索引第一行及其所有列。该代码使用每个观测值的唯一生存函数估计值,从观测值在曲线上的当前位置预测30天的生存概率



来自@thc的答案实际上最终为我指明了正确的方向

您还应该将您的帖子标记为
[r]
.Done。谢谢。您从哪里获得
lung
数据?生存软件包您还应该将您的帖子标记为
[r]
.Done。谢谢。你从哪里得到肺的数据?生存包这实际上不是我需要的。这段代码传递了一个要预测的时间向量,但我只需要向每个测试实例传递一个时间,即它的时间+30天。只需更改查询,使每一行都是一个测试实例。我不明白你的意思。你能在我给出的代码示例中实现它吗?是的,但是即使它进行了冗余计算,它仍然要快得多。我更新了上面的代码,并提供了基准进行验证。您可以通过对时间进行排序来提取所需的向量。@thc,我可能遗漏了一些内容,但这两个函数的结果不相等<代码>surv_preds2[1,]==surv_preds2[2,]
但是
surv_preds!=surv_preds2[1,]
,即使在排序之后,这实际上也不是我需要的。这段代码传递了一个要预测的时间向量,但我只需要向每个测试实例传递一个时间,即它的时间+30天。只需更改查询,使每一行都是一个测试实例。我不明白你的意思。你能在我给出的代码示例中实现它吗?是的,但是即使它进行了冗余计算,它仍然要快得多。我更新了上面的代码,并提供了基准进行验证。您可以通过对时间进行排序来提取所需的向量。@thc,我可能遗漏了一些内容,但这两个函数的结果不相等<代码>surv_preds2[1,]==surv_preds2[2,]但是
surv_preds!=surv_preds2[1,]
,即使在排序之后也要感谢您的输入。我似乎找不到解决此问题的方法。Purrly的例子很好,但不幸的是对于我的预期目的来说仍然太慢。如果总而言之,这可能是我唯一的选择。谢谢你的意见。我似乎找不到解决这个问题的办法。Purrly的例子很好,但不幸的是对于我的预期目的来说仍然太慢。如果一切顺利,这可能是我唯一的选择。