【问题标题】:Avoiding nested loops in R避免 R 中的嵌套循环
【发布时间】:2013-11-17 19:58:16
【问题描述】:

我有这组序列,其中包含 2 个变量作为第三个变量(设备)。现在我想将每个设备的序列分成 300 个组。dsl 是一个数据帧,其中包含 d 是设备 ID,s 是长度为 300 的序列数。

首先,我标记(列Sid)所有序列rep(1,300),然后是rep(2,300),依此类推,直到rep(s,300)。需要忽略未标记的任何内容,即带有初始化标签(= 0)的内容。实际的标记发生在 seqid 向量上。

我必须这样做,因为我想堆叠 300 个数据点的集合,然后转置它。这将形成我的 predata data.frame 的一行。对于每个 predata 数据帧,我正在做一个 k-means 来生成 5 个我存储在最终数据中的集群。

基本上对于每个设备,我都会有 5 个集群,然后我可以通过引用最终数据中的行号(映射到设备 ID)来拉取这些集群。

#subset processed data by device

for (ds in 1:387){
  d <- dsl[ds,1]
  s <- dsl[ds,3]

  temp.data <- subset(data,data$Device==d)
  temp.data$Sid <- 0
  temp.data[1:(s*300),4] <- rep(1:300,s)
  temp.data <- subset(temp.data,temp.data$Sid!="0")

  seqid <- NA

  for (j in 1:s){ seqid[(300*(j-1)+1):(300*j)] <- j }

  temp.data$Sid <- seqid

  predata <- as.data.frame(matrix(numeric(0),s,600))


  for(k in 1:s){
    temp.data2 <- subset(temp.data[,c(1,2)], temp.data$Sid==k)
    predata[k,] <- t(stack(temp.data2)[,1])
  }

  ob <- kmeans(predata,5,iter.max=10,algorithm="Hartigan-Wong")
  finaldata <- rbind(finaldata,(unique(fitted(ob,method="centers"))))
}

作为 R 的菜鸟,我最终得到了 3 个嵌套循环(该函数确实适用于最外层循环为一个值)。这需要 5 小时并运行。需要一种更快的方法来解决这个问题。

我们将不胜感激。

谢谢

【问题讨论】:

标签: r nested vectorization


【解决方案1】:

好的,我将建议您在循环中彻底简化您的代码。然而,在没有样本数据的情况下,很难验证我是否确实假设了正确的事情。所以请确保我的predata 实际上等于你的。

首先是代码:

for (ds in 1:387){
  d <- dsl[ds,1]
  s <- dsl[ds,3]

  temp.data <- subset(data,data$Device==d)
  temp.data <- temp.data[1:(s*300),]

  predata <- cbind(matrix(temp.data[,1], byrow=T, ncol=300), matrix(temp.data[,2], byrow=T, ncol=300))

  ob <- kmeans(predata,5,iter.max=10,algorithm="Hartigan-Wong")
  finaldata <- rbind(finaldata,(unique(fitted(ob,method="centers"))))
}

我了解您在做什么:从您的 subset(data, data$Devide == d 中获取第一个 300*s 元素。这可以使用命令轻松完成

temp.data <- temp.data[1:(s*300),]

然后,您收集具有第一行 c(temp.data[1:300, 1], temp.data[1:300, 2]) 的矩阵,以此类推所有其他行。我使用上面的matrix 命令执行此操作。

我假设您的外部循环可以转换为对tapply 或类似的调用,但因此,我们需要更多上下文。

【讨论】:

  • 我知道涉及多个循环。我认为主要的绊脚石是找到某种方法来使用像“tapply”这样的内置 R 函数,它会分解数据,处理碎片并组装在一个单独的变量中。如果有特定的方法可以解决这个问题,那么这可以应用于问题。这可能吗?
  • @user2977721 你试过我上面的版本吗?根据s 的大小,我们可能已经节省了很多时间。为了简化你的外循环,我们肯定需要更多的上下文,可能还需要一个样本数据集。但是,我担心kmeans 也可能是瓶颈的一部分。
  • 还有一点:尝试使用Rprof 分析您的循环。如果subsetrbind 命令浪费了大部分时间,apply 的某些版本可能会加快速度。如果瓶颈是kmeans,那么您将面临完全不同的挑战。如上所述生成predata 应该不需要太多时间。
猜你喜欢
  • 2021-08-19
  • 2012-09-01
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
  • 2017-08-27
  • 2017-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多