从 sapply 返回 data.tables 的列表
Returning a list of data.tables from sapply
我有一个有趣的问题。我有一些未知数量的巨大表,但至少有 2 个。它们具有相同的架构,我想从每个表中提取子集并创建一个专门的交叉连接,以便我可以组合各个部分。
所以从一个包含 2 个 data.table 个对象的简单示例开始:
DT1 <- data.table(A = rep(1:2, each = 2), B = rep(1:2, 2), C = sample(4))
DT2 <- data.table(A = rep(1:2, 2), B = sample(4), C = rep(1:2, each = 2))
> DT1
A B C
1 1 2
1 2 3
2 1 1
2 2 4
> DT2
A B C
1 2 1
2 1 1
1 3 2
2 4 2
因为我最终不知道我必须对多少表进行子集化,所以我创建了一个列表并将其传递给函数以使用 sapply 进行子集化:
tables = list(DT1, DT2)
foo <- function(dt, value) {
result <- dt[A == value,]
return(result)
}
combined <- sapply(tables, foo, value = 1)
然而,合并后的结果是没有模式的向量混乱。我想取回的是 data.table 的列表。 foo 函数 returns a data.table 但结果在 sapply 中被打乱了。如何修改代码来执行类似这样的操作?
combined <- list(DT1[A == 1,], DT2[A == 1])
产生 data.table 的列表
> combined
[[1]]
A B C
1: 1 1 2
2: 1 2 3
[[2]]
A B C
1: 1 2 1
2: 1 3 2
TIA 一如既往。
foo <- function(dt, value) {
result <- dt[A == value,]
return(result)
}
combined <- lapply(tables, foo, value = 1)
另一种方法,使用 dplyr
和 lapply
,如下所示。扩展这项工作可以使其更具活力。
library(dplyr)
library(data.table)
set.seed(42)
DT1 <- data.table(A = rep(1:2, each = 2), B = rep(1:2, 2), C = sample(4))
DT2 <- data.table(A = rep(1:2, 2), B = sample(4), C = rep(1:2, each = 2))
DT3 <- data.table(A = rep(1:2, each = 2), B = sample(4), C = rep(1:2, times = 2))
DT4 <- data.table(A = rep(1:2, 2), B = sample(4), C = rep(1:2, each = 2))
# View the data.tables
list(DT1, DT2, DT3, DT4)
# [[1]]
# A B C
# 1: 1 1 4
# 2: 1 2 3
# 3: 2 1 1
# 4: 2 2 2
#
# [[2]]
# A B C
# 1: 1 3 1
# 2: 2 2 1
# 3: 1 4 2
# 4: 2 1 2
#
# [[3]]
# A B C
# 1: 1 3 1
# 2: 1 4 2
# 3: 2 1 1
# 4: 2 2 2
#
# [[4]]
# A B C
# 1: 1 4 1
# 2: 2 1 1
# 3: 1 3 2
# 4: 2 2 2
#
# Get a List of data.tables For A == 1
lapply(list(DT1, DT2, DT3, DT4),
function(.data, ...) { as.data.table(dplyr::filter_(.data, ...)) },
~ A == 1)
# [[1]]
# A B C
# 1: 1 1 4
# 2: 1 2 3
#
# [[2]]
# A B C
# 1: 1 3 1
# 2: 1 4 2
#
# [[3]]
# A B C
# 1: 1 3 1
# 2: 1 4 2
#
# [[4]]
# A B C
# 1: 1 4 1
# 2: 1 3 2
#
# Get a List of data.tables For A == 2
lapply(list(DT1, DT2, DT3, DT4),
function(.data, ...) { as.data.table(dplyr::filter_(.data, ...)) },
~ A == 2)
# [[1]]
# A B C
# 1: 2 1 1
# 2: 2 2 2
#
# [[2]]
# A B C
# 1: 2 2 1
# 2: 2 1 2
#
# [[3]]
# A B C
# 1: 2 1 1
# 2: 2 2 2
#
# [[4]]
# A B C
# 1: 2 1 1
# 2: 2 2 2
#
扩展此方法以允许更复杂的过滤条件很容易。您需要做的就是在 lapply
调用中添加条件。
# Get a list of data.tables for A == 2 and B == 1
lapply(list(DT1, DT2, DT3, DT4),
function(.data, ...) { as.data.table(dplyr::filter_(.data, ...)) },
~ A == 2, ~ B == 1)
# [[1]]
# A B C
# 1: 2 1 1
#
# [[2]]
# A B C
# 1: 2 1 2
#
# [[3]]
# A B C
# 1: 2 1 1
#
# [[4]]
# A B C
# 1: 2 1 1
#
我有一个有趣的问题。我有一些未知数量的巨大表,但至少有 2 个。它们具有相同的架构,我想从每个表中提取子集并创建一个专门的交叉连接,以便我可以组合各个部分。
所以从一个包含 2 个 data.table 个对象的简单示例开始:
DT1 <- data.table(A = rep(1:2, each = 2), B = rep(1:2, 2), C = sample(4))
DT2 <- data.table(A = rep(1:2, 2), B = sample(4), C = rep(1:2, each = 2))
> DT1
A B C
1 1 2
1 2 3
2 1 1
2 2 4
> DT2
A B C
1 2 1
2 1 1
1 3 2
2 4 2
因为我最终不知道我必须对多少表进行子集化,所以我创建了一个列表并将其传递给函数以使用 sapply 进行子集化:
tables = list(DT1, DT2)
foo <- function(dt, value) {
result <- dt[A == value,]
return(result)
}
combined <- sapply(tables, foo, value = 1)
然而,合并后的结果是没有模式的向量混乱。我想取回的是 data.table 的列表。 foo 函数 returns a data.table 但结果在 sapply 中被打乱了。如何修改代码来执行类似这样的操作?
combined <- list(DT1[A == 1,], DT2[A == 1])
产生 data.table 的列表
> combined
[[1]]
A B C
1: 1 1 2
2: 1 2 3
[[2]]
A B C
1: 1 2 1
2: 1 3 2
TIA 一如既往。
foo <- function(dt, value) {
result <- dt[A == value,]
return(result)
}
combined <- lapply(tables, foo, value = 1)
另一种方法,使用 dplyr
和 lapply
,如下所示。扩展这项工作可以使其更具活力。
library(dplyr)
library(data.table)
set.seed(42)
DT1 <- data.table(A = rep(1:2, each = 2), B = rep(1:2, 2), C = sample(4))
DT2 <- data.table(A = rep(1:2, 2), B = sample(4), C = rep(1:2, each = 2))
DT3 <- data.table(A = rep(1:2, each = 2), B = sample(4), C = rep(1:2, times = 2))
DT4 <- data.table(A = rep(1:2, 2), B = sample(4), C = rep(1:2, each = 2))
# View the data.tables
list(DT1, DT2, DT3, DT4)
# [[1]]
# A B C
# 1: 1 1 4
# 2: 1 2 3
# 3: 2 1 1
# 4: 2 2 2
#
# [[2]]
# A B C
# 1: 1 3 1
# 2: 2 2 1
# 3: 1 4 2
# 4: 2 1 2
#
# [[3]]
# A B C
# 1: 1 3 1
# 2: 1 4 2
# 3: 2 1 1
# 4: 2 2 2
#
# [[4]]
# A B C
# 1: 1 4 1
# 2: 2 1 1
# 3: 1 3 2
# 4: 2 2 2
#
# Get a List of data.tables For A == 1
lapply(list(DT1, DT2, DT3, DT4),
function(.data, ...) { as.data.table(dplyr::filter_(.data, ...)) },
~ A == 1)
# [[1]]
# A B C
# 1: 1 1 4
# 2: 1 2 3
#
# [[2]]
# A B C
# 1: 1 3 1
# 2: 1 4 2
#
# [[3]]
# A B C
# 1: 1 3 1
# 2: 1 4 2
#
# [[4]]
# A B C
# 1: 1 4 1
# 2: 1 3 2
#
# Get a List of data.tables For A == 2
lapply(list(DT1, DT2, DT3, DT4),
function(.data, ...) { as.data.table(dplyr::filter_(.data, ...)) },
~ A == 2)
# [[1]]
# A B C
# 1: 2 1 1
# 2: 2 2 2
#
# [[2]]
# A B C
# 1: 2 2 1
# 2: 2 1 2
#
# [[3]]
# A B C
# 1: 2 1 1
# 2: 2 2 2
#
# [[4]]
# A B C
# 1: 2 1 1
# 2: 2 2 2
#
扩展此方法以允许更复杂的过滤条件很容易。您需要做的就是在 lapply
调用中添加条件。
# Get a list of data.tables for A == 2 and B == 1
lapply(list(DT1, DT2, DT3, DT4),
function(.data, ...) { as.data.table(dplyr::filter_(.data, ...)) },
~ A == 2, ~ B == 1)
# [[1]]
# A B C
# 1: 2 1 1
#
# [[2]]
# A B C
# 1: 2 1 2
#
# [[3]]
# A B C
# 1: 2 1 1
#
# [[4]]
# A B C
# 1: 2 1 1
#