使用等效的purrr ::: map迭代data.table

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用等效的purrr ::: map迭代data.table相关的知识,希望对你有一定的参考价值。

我想迭代data.table,就像purrr::map那样。虽然我能够通过将data.table转换为data.frame中的data.table来应用purrr::map函数,但我想知道data.table是否具有可以使用purrr::map进行内置的内置。我问这个是因为我不确定purrr::map在速度和内存方面的表现。与dplyr处理大型数据集时相比,我对data.table的速度和内存利用率感到失望。

我研究了stackoverflow,发现在Iterate through data tables线程上接受的答案使用了for循环。出于性能原因,我不是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::mapdata.table的示例代码

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])

我并不太关心输出,但我想知道有哪些替代品可用于基于特定列迭代data.table。我很感激任何想法。

答案

通过重复[],例如,可以很好地完成管道数据表。 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

更新:我想可以有一个更清洁的解决方案,无需导入magrittr和没有$子集

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
另一答案

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

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

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

以上是关于使用等效的purrr ::: map迭代data.table的主要内容,如果未能解决你的问题,请参考以下文章

purrr::map 中的第一个波浪号是啥意思

将 purrr::map2() 与 dbplyr 一起使用

使用 purrr::map 时获得不同的 ggplot

使用 purrr::map2 具有所有变量排列的模型

R语言ggplot2可视化:使用purrr包的map函数基于嵌套的dataframe数据绘制多个可视化图像(包含3个子图)

R语言ggplot2可视化:使用purrr包的map函数基于嵌套的dataframe数据绘制多个可视化图像(包含2个子图)