【问题标题】:Alternate to using loops to replace values for big datasets in R?替代使用循环替换 R 中大数据集的值?
【发布时间】:2014-09-01 19:13:20
【问题描述】:

我有一个大型(约 450 万条记录)数据框,其中几列已通过散列匿名,我没有密钥,但我确实希望将它们重新编号为更清晰的数字以帮助分析.

为此,例如,我推断“campaignID”在 4.5 条记录中具有 161 个唯一元素,并创建了一个向量来保存这些元素。然后我尝试编写一个 FOR/IF 循环来使用唯一元素向量搜索整个数据集 - 对于“campaignID”的每个值,它都会根据唯一元素向量进行检查,当它找到匹配项时,它会返回唯一元素向量的索引值作为新的活动 ID。

campaigns_length <- length(unique_campaign)
dataset_length <- length(dataset$campaignId)


for (i in 1:dataset_length){
for (j in 1:campaigns_length){
if (dataset$campaignId[[i]] == unique_campaign[[j]]){
  dataset$campaignId[[i]] <- j
}}}

问题当然是,虽然它有效,但需要很长时间 - 我不得不在 12 小时后停止它!有谁能想到一种更好的方法,它更快、更便宜、计算成本更低?

【问题讨论】:

标签: r


【解决方案1】:

你可以使用match

dataset$campaignId <- match(dataset$campaignId, unique_campaign)

Is there an R function for finding the index of an element in a vector?

【讨论】:

    【解决方案2】:

    您可以使用类似字典的结构来避免内部循环:

    id_dict = list()
    for (id in 1:unique_campaign) {
        id_dict[[ unique_campaign[[id]] ]] = id
    }
    
    for (i in 1:dataset_length) {
        dataset$campaignId[[i]] = id_dict[[ dataset$campaignId[[i]] ]]
    }
    

    正如in this post 指出的那样,列表没有 O(1) 访问权限,因此它不会将所需时间除以 161,而是根据您列表中 id 的重新分区,除以较小的因子。
    此外,您的代码如此缓慢的主要原因是因为您正在使用那些效率低下的列表(如果i 很大,单独的dataset$campaignId[[i]] 可能会花费很多时间)。查看hash package,它提供对元素的 O(1) 访问(另请参阅this thread on hashed structures in R

    【讨论】:

      【解决方案3】:

      在这种情况下,您可能会从使用 data.table 包中受益:

      library(data.table)
      
      n = 10000000
      
      unique_campaign = sample(1:10000, 169)
      
      dataset = data.table(
          campaignId = sample(unique_campaign, n, TRUE),
          profit = round(runif(n, 100, 1000))
      )
      dataset[, campaignId := match(campaignId, unique_campaign)]
      

      这个包含 1000 万行的示例只需几秒钟即可运行。

      【讨论】:

        猜你喜欢
        • 2017-06-06
        • 2016-07-24
        • 1970-01-01
        • 2021-10-19
        • 1970-01-01
        • 1970-01-01
        • 2020-07-14
        • 2020-10-01
        • 2011-02-17
        相关资源
        最近更新 更多