代码之家  ›  专栏  ›  技术社区  ›  watchtower

使用purrr:::map的等效项来迭代数据。桌子

  •  5
  • watchtower  · 技术社区  · 7 年前

    我想反复浏览 data.table ,正如 purrr::map 做当我能够申请的时候 数据桌子 转换函数 data.frame 数据桌子 在…内 purrr::映射 ,我想知道 数据桌子 有一些内置的东西,可以拒绝使用 purrr::映射 . 我问这个是因为我不确定 purrr::映射 在速度和所需内存方面的性能。我对 dplyr 的速度和内存利用率 数据桌子 处理大型数据集时。

    我研究了stackoverflow,发现 Iterate through data tables 线程已使用 for 环我不太喜欢 对于 出于性能原因进行循环。

    以下是示例数据文件:

    dput(Input_File)
    structure(list(Zone = c("East", "East", "East", "East", "East", 
    "East", "East", "West", "West", "West", "West", "West", "West", 
    "West"), Fiscal.Year = c(2016, 2016, 2016, 2016, 2016, 2016, 
    2017, 2016, 2016, 2016, 2017, 2017, 2018, 2018), Transaction.ID = c(132, 
    133, 134, 135, 136, 137, 171, 171, 172, 173, 175, 176, 177, 178
    ), L.Rev = c(3, 0, 0, 1, 0, 0, 2, 1, 1, 2, 2, 1, 2, 1), L.Qty = c(3, 
    0, 0, 1, 0, 0, 1, 1, 1, 2, 2, 1, 2, 1), A.Rev = c(0, 0, 0, 1, 
    1, 1, 0, 0, 0, 0, 0, 1, 0, 0), A.Qty = c(0, 0, 0, 2, 2, 3, 0, 
    0, 0, 0, 0, 3, 0, 0), I.Rev = c(4, 4, 4, 0, 1, 0, 3, 0, 0, 0, 
    1, 0, 1, 1), I.Qty = c(2, 2, 2, 0, 1, 0, 3, 0, 0, 0, 1, 0, 1, 
    1)), .Names = c("Zone", "Fiscal.Year", "Transaction.ID", "L.Rev", 
    "L.Qty", "A.Rev", "A.Qty", "I.Rev", "I.Qty"), row.names = c(NA, 
    14L), class = "data.frame")
    

    下面是示例代码 purrr::映射 数据桌子

    UZone <- unique(Input_File$Zone)
    FYear <- unique(Input_File$Fiscal.Year)
    a<-purrr::map(UZone, ~ dplyr::filter(Input_File, Zone == .)) %>%
       purrr::map(~ data.table::as.data.table(.)) %>%
       purrr::map(~ .[,.(sum = sum(L.Rev)),by=Fiscal.Year])
    

    我不太关心输出,但我想知道有哪些替代方案可以迭代 数据桌子 基于特定列。如果有任何想法,我将不胜感激。

    2 回复  |  直到 7 年前
        1
  •  2
  •   dmi3kno    7 年前

    管道数据表可以通过重复 [] ,例如。 DT[][][] . 对于列表,我认为除了 magrittr . 其余部分可以通过链接完成 lapply

    library(data.table)
    library(magrittr)
    
    Input_File <- data.table(Input_File)
    
    UZone <- unique(Input_File$Zone)
    FYear <- unique(Input_File$Fiscal.Year)
    
    lapply(UZone, function(x) Input_File[Zone==x]) %>% 
      lapply(function(x) x[,.(sum=sum(L.Rev)), by=Fiscal.Year])
    

    如果您想迭代 结束 列,您可能需要查看 this solution

    更新:我想可能会有一个更干净的解决方案,而无需导入 马格里特 而且没有 $ 子集设置

    library(data.table)
    
    Input_File <- data.table(Input_File)
    
    by_zone_lst <- lapply(Input_File[,unique(Zone)], function(x) Input_File[Zone==x])
    summary_lst <- lapply(by_zone_lst, function(y) y[,.(sum=sum(L.Rev)), by=Fiscal.Year])
    
    summary_lst
    
        2
  •  1
  •   Uwe    7 年前

    我不确定问题的背后是什么,但我更喜欢

    library(data.table)
    setDT(Input_File)[, .(sum = sum(L.Rev)), by = .(Zone, Fiscal.Year)]
    
       Zone Fiscal.Year sum
    1: East        2016   4
    2: East        2017   2
    3: West        2016   4
    4: West        2017   3
    5: West        2018   3
    

    over OP进近返回 a

    [[1]]
       Fiscal.Year sum
    1:        2016   4
    2:        2017   2
    
    [[2]]
       Fiscal.Year sum
    1:        2016   4
    2:        2017   3
    3:        2018   3