【问题标题】:How to optimize and faster for loop when handling large dataset in R?在 R 中处理大型数据集时如何优化和更快地循环?
【发布时间】:2017-06-07 09:08:13
【问题描述】:

目前,我正在处理数据转换。数据不是特别大,大约190k行。

我写了一个这样的for循环:

for (i in 1:nrow(df2)){
#a
record.a <- df[which(df$first_lat==df2[i,"third_lat"] 
            & df$first_lon==df2[i,"third_lon"] 
            & df$sixth_lat==df2[i,"fourth_lat"] 
            & df$sixth_lon==df2[i,"fourth_lon"] 
            & df[,4]==df2[i,4] 
            & df[,3]==df2[i,5]),]
df2[i,18] <- ifelse(nrow(record.a) != 0,record.a$order_cnt,NA)

#b
record.b <- df[which(df$fifth_lat==df2[i,"third_lat"] 
            & df$fifth_lon==df2[i,"third_lon"] 
            & df$sixth_lat==df2[i,"second_lat"] 
            & df$sixth_lon==df2[i,"second_lon"] 
            & df[,4]==df2[i,4] 
            & df[,3]==df2[i,5]),]
df2[i,19] <- ifelse(nrow(record.b) != 0,record.b$order_cnt,NA)

#c
record.c <- df[which(df$fifth_lat==df2[i,"first_lat"] 
            & df$fifth_lon==df2[i,"first_lon"] 
            & df$fourth_lat==df2[i,"second_lat"] 
            & df$fourth_lon==df2[i,"second_lon"] 
            & df[,4]==df2[i,4] 
            & df[,3]==df2[i,5]),]
df2[i,20] <- ifelse(nrow(record.c) != 0,record.c$order_cnt,NA)

#d
record.d <- df[which(df$third_lat==df2[i,"first_lat"] 
            & df$third_lon==df2[i,"first_lon"] 
            & df$fourth_lat==df2[i,"sixth_lat"] 
            & df$fourth_lon==df2[i,"sixth_lon"] 
            & df[,4]==df2[i,4] 
            & df[,3]==df2[i,5]),]
df2[i,21] <- ifelse(nrow(record.d) != 0,record.d$order_cnt,NA)

#e
record.e <- df[which(df$third_lat==df2[i,"fifth_lat"] 
            & df$third_lon==df2[i,"fifth_lon"] 
            & df$second_lat==df2[i,"sixth_lat"] 
            & df$second_lon==df2[i,"sixth_lon"] 
            & df[,4]==df2[i,4] 
            & df[,3]==df2[i,5]),]
df2[i,22] <- ifelse(nrow(record.e) != 0,record.e$order_cnt,NA)

#f
record.f <- df[which(df$first_lat==df2[i,"fifth_lat"] 
            & df$first_lon==df2[i,"fifth_lon"] 
            & df$second_lat==df2[i,"fourth_lat"] 
            & df$second_lon==df2[i,"fourth_lon"] 
            & df[,4]==df2[i,4] 
            & df[,3]==df2[i,5]),]
df2[i,23] <- ifelse(nrow(record.f) != 0,record.f$order_cnt,NA)
}

所以,基本上,我需要分别从 df 中用 6 个条件填写 df2 的 6 列。在 for 循环中,nrow(df2) 约为 190k。它运行超级慢。但我用 view(df2) 来检查它,它运行良好。那么有什么方法可以让它更快吗?将来我可能会将相同的数据转换应用于更大的数据集。

df: df

df2: df2

数据是关于地图上的网格。 df2 基本上是 df 的一个子集,但添加了 6 个额外的列。 df 和 df2 具有相同的 lon 和 lat 信息。

每个 grid_id 代表地图中的一个六边形区域。每个六边形通过两对 lon 和 lat 连接到其他六个六边形。我想要做的是从六个周围的六边形(在 df 中)中找到一个特定值来填充 df2 中的列(a、b、c、d、e、f)。另外,我还需要另外两个条件,即小时,十分钟间隔。 (df[,4]==df2[i,4] & df[,3]==df2[i,5]))

所以我认为逻辑是:

  1. 对于 df2 中的每个 grid_id、小时、十分钟间隔(1 行)
  2. 在df中找到对应的6个grid_ids(6行),时间相同,十分钟间隔
  3. 将 order_cnt 从这 6 行填充到 df2 中的 a、b、c、d、e、f 列中

【问题讨论】:

  • 您能否提供一个可重现的小示例,例如将输出 dput(head(df))dput(head(df2[,18:23])) 粘贴到问题中。
  • for 循环几乎总是不必要的,但您需要分享一些示例数据和预期结果,以便更容易理解您的需求。也许也可以简化问题 - 更少的列
  • 目前您不太可能得到完整的答案,因为该问题不可重现,即没有示例数据显示 df 和 df2 的结构。加快速度的最可能方法似乎是对 6 个块中的每一个块使用 merge 函数以避免 for 循环
  • 感谢您的回复。我刚刚编辑了我的帖子以添加更多信息。请再次检查。

标签: r loops


【解决方案1】:

如果您从当前的df2[,1:17] 开始,您可以使用合并命令添加df[,18]

df2 <- merge(df[,c("first_lat","first_lon","sixth_lat","sixth_lon","col4name","col5name","order_cn")],
      df2,
      by.x=c("first_lat","first_lon","sixth_lat","sixth_lon","col4name","col5name"),
      by.y=c("third_lat","third_lon","fourth_lat","fourth_lon","col4name","col3name"),
      all.y=TRUE)

您需要将 col4name 替换为第四列的名称,依此类推 - 我无法从屏幕截图中看到可能是什么。可以轻松生成此命令的另外五个版本以添加其他五列。由于该操作有时对整个向量起作用,因此它可能比循环更快。由于未以合适的格式提供数据,因此未进行测试。

【讨论】:

    猜你喜欢
    • 2017-04-27
    • 2022-01-12
    • 1970-01-01
    • 2013-09-05
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多