展开两个大数据文件并应用data.table?
Expand two large data files and apply using data.table?
我正在尝试将一个函数应用于两个数据集 df1
和 df2
,其中 df1
包含 (a, b)
并且可以是 100 万行长,并且 df2
包含 (x, y, z)
并且可以非常大,从 ~100 到 >10,000 不等。我想对两个数据集的每个组合应用函数 foo
,然后对第二个数据集求和。
foo <- function(a, b, x, y, z) a + b + x + y + z
df1 <- data.frame(a = 1:10, b = 11:20)
df2 <- data.frame(x= 1:5, y = 21:25, z = 31:35)
我用来应用此功能的代码(取自@jlhoward 此处How to avoid multiple loops with multiple variables in R)
foo.new <- function(p1, p2) {
p1 = as.list(p1); p2 = as.list(p2)
foo(p1$a, p1$b, p2$x, p2$y, p2$z)
}
indx <- expand.grid(indx2 = seq(nrow(df2)), indx1 = seq(nrow(df1)))
result <- with(indx, foo.new(df1[indx1, ], df2[indx2, ]))
sums <- aggregate(result, by = list(rep(seq(nrow(df1)), each = nrow(df2))), sum)
但是,随着 df2
变大 (>1000),我很快 运行 内存不足来执行上面的 result
功能(运行ning 64 位 PC 和 32GB内存)。
我已经阅读了很多关于 data.table
的内容,但无法评估其中是否有有助于节省内存的功能。可以替换 with
并在 result
步骤创建较小的文件,或在 index
步骤创建 expand.grid
的东西,这会创建迄今为止最大的文件。
这是一个 data.table 解决方案:应该很快:
library(data.table)
indx<-CJ(indx1=seq(nrow(df2)),indx2=seq(nrow(df1))) #CJ is data.table function for expand.grid
indx[,`:=`(result=foo.new(df1[indx1, ], df2[indx2, ]),Group.1=rep(seq(nrow(df1)), each = nrow(df2)))][,.(sums=sum(result)),by=Group.1]
Group.1 sums
1: 1 355
2: 2 365
3: 3 375
4: 4 385
5: 5 395
6: 6 405
7: 7 415
8: 8 425
9: 9 435
10: 10 445
我正在尝试将一个函数应用于两个数据集 df1
和 df2
,其中 df1
包含 (a, b)
并且可以是 100 万行长,并且 df2
包含 (x, y, z)
并且可以非常大,从 ~100 到 >10,000 不等。我想对两个数据集的每个组合应用函数 foo
,然后对第二个数据集求和。
foo <- function(a, b, x, y, z) a + b + x + y + z
df1 <- data.frame(a = 1:10, b = 11:20)
df2 <- data.frame(x= 1:5, y = 21:25, z = 31:35)
我用来应用此功能的代码(取自@jlhoward 此处How to avoid multiple loops with multiple variables in R)
foo.new <- function(p1, p2) {
p1 = as.list(p1); p2 = as.list(p2)
foo(p1$a, p1$b, p2$x, p2$y, p2$z)
}
indx <- expand.grid(indx2 = seq(nrow(df2)), indx1 = seq(nrow(df1)))
result <- with(indx, foo.new(df1[indx1, ], df2[indx2, ]))
sums <- aggregate(result, by = list(rep(seq(nrow(df1)), each = nrow(df2))), sum)
但是,随着 df2
变大 (>1000),我很快 运行 内存不足来执行上面的 result
功能(运行ning 64 位 PC 和 32GB内存)。
我已经阅读了很多关于 data.table
的内容,但无法评估其中是否有有助于节省内存的功能。可以替换 with
并在 result
步骤创建较小的文件,或在 index
步骤创建 expand.grid
的东西,这会创建迄今为止最大的文件。
这是一个 data.table 解决方案:应该很快:
library(data.table)
indx<-CJ(indx1=seq(nrow(df2)),indx2=seq(nrow(df1))) #CJ is data.table function for expand.grid
indx[,`:=`(result=foo.new(df1[indx1, ], df2[indx2, ]),Group.1=rep(seq(nrow(df1)), each = nrow(df2)))][,.(sums=sum(result)),by=Group.1]
Group.1 sums
1: 1 355
2: 2 365
3: 3 375
4: 4 385
5: 5 395
6: 6 405
7: 7 415
8: 8 425
9: 9 435
10: 10 445