使用 purrr:::map 的等价物遍历 data.table
Use equivalent of purrr:::map to iterate through data.table
我想遍历 data.table
,就像 purrr::map
一样。虽然我能够通过将 data.frame
转换为 purrr::map
中的 data.table
来应用 data.table
函数,但我想知道 data.table
是否有一些内置的东西可以放弃使用 purrr::map
。我问这个是因为我不确定 purrr::map
在速度和所需内存方面的性能。在处理大型数据集时,与 data.table
相比,我对 dplyr
的速度和内存利用率感到失望。
我研究了 Whosebug,发现 线程上接受的答案使用了 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::map
和 data.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])
如果您想遍历 over 列,您可能想看看
更新:我想可能会有一个更简洁的解决方案,无需导入 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
我想遍历 data.table
,就像 purrr::map
一样。虽然我能够通过将 data.frame
转换为 purrr::map
中的 data.table
来应用 data.table
函数,但我想知道 data.table
是否有一些内置的东西可以放弃使用 purrr::map
。我问这个是因为我不确定 purrr::map
在速度和所需内存方面的性能。在处理大型数据集时,与 data.table
相比,我对 dplyr
的速度和内存利用率感到失望。
我研究了 Whosebug,发现 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::map
和 data.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])
如果您想遍历 over 列,您可能想看看
更新:我想可能会有一个更简洁的解决方案,无需导入 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