gpt4 book ai didi

r - 在 data.table R 中使用 lapply .SD

转载 作者:行者123 更新时间:2023-12-01 23:31:50 27 4
gpt4 key购买 nike

我不太清楚.SDby的使用。

例如,下面的代码片段是否意味着:“将 DT 中的所有列更改为除 AB 之外的因子?” data.table 手册中还提到:“.SD 指每个组的 data.table 的子集(不包括分组列) )"- 所以列 AB 被排除在外?

DT = DT[ ,lapply(.SD, as.factor), by=.(A,B)]

但是,我还了解到,当进行聚合时,by 的意思类似于 SQL 中的“group by”。例如,如果我想对除 AB 之外的所有列进行求和(如 SQL 中的 colsum),我是否仍然使用类似的东西?或者在这种情况下,下面的代码是否意味着对 AB 列中的值进行求和和分组? (如 SQL 中那样,按 A,B 求和并分组)

DT[,lapply(.SD,sum),by=.(A,B)]

那么如何对除 AB 之外的所有列进行简单的 colsum 呢?

最佳答案

为了用一个例子来说明上面的评论,让我们来看一下

set.seed(10238)
# A and B are the "id" variables within which the
# "data" variables C and D vary meaningfully
DT = data.table(
A = rep(1:3, each = 5L),
B = rep(1:5, 3L),
C = sample(15L),
D = sample(15L)
)
DT
# A B C D
# 1: 1 1 14 11
# 2: 1 2 3 8
# 3: 1 3 15 1
# 4: 1 4 1 14
# 5: 1 5 5 9
# 6: 2 1 7 13
# 7: 2 2 2 12
# 8: 2 3 8 6
# 9: 2 4 9 15
# 10: 2 5 4 3
# 11: 3 1 6 5
# 12: 3 2 12 10
# 13: 3 3 10 4
# 14: 3 4 13 7
# 15: 3 5 11 2

比较以下内容:

#Sum all columns
DT[ , lapply(.SD, sum)]
# A B C D
# 1: 30 45 120 120

#Sum all columns EXCEPT A, grouping BY A
DT[ , lapply(.SD, sum), by = A]
# A B C D
# 1: 1 15 38 43
# 2: 2 15 30 49
# 3: 3 15 52 28

#Sum all columns EXCEPT A
DT[ , lapply(.SD, sum), .SDcols = !"A"]
# B C D
# 1: 45 120 120

#Sum all columns EXCEPT A, grouping BY B
DT[ , lapply(.SD, sum), by = B, .SDcols = !"A"]
# B C D
# 1: 1 27 29
# 2: 2 17 30
# 3: 3 33 11
# 4: 4 23 36
# 5: 5 20 14

一些注意事项:

  • 您说“以下代码片段是否...更改 DT 中的所有列...”

答案是,这对于data.table非常重要。返回的对象是一个new data.table,并且DT中的所有列都与运行代码之前完全相同。

  • 您提到想要更改列类型

再次引用上面的观点,请注意您的代码 (DT[ , lapply(.SD, as.factor)]) 返回一个 数据.table 并且根本不改变DT。执行此操作的一种(不正确)方法是使用 base 中的 data.frame 来完成,即覆盖旧的 data .table 与您返回的新 data.table,即 DT = DT[ , lapply(.SD, as.factor)]

这是一种浪费,因为它涉及创建 DT 的副本,当 DT 很大时,这可能会成为效率 killer 。解决此问题的正确 data.table 方法是使用 `:=` 通过引用更新列,例如 DT[ , names(DT) := lapply(.SD, as.factor)],它不会创建数据的副本。请参阅data.table's reference semantics vignette了解更多相关信息。

  • 您提到比较 lapply(.SD, sum)colSums 的效率。 sumdata.table 中进行了内部优化(您可以从在 中添加 verbose = TRUE 参数的输出中注意到这是正确的) []);要查看实际效果,让我们稍微增强一下 DT 并运行基准测试:

结果:

library(data.table)
set.seed(12039)
nn = 1e7; kk = seq(100L)
DT = setDT(replicate(26L, sample(kk, nn, TRUE), simplify=FALSE))
DT[ , LETTERS[1:2] := .(sample(100L, nn, TRUE), sample(100L, nn, TRUE))]

library(microbenchmark)
microbenchmark(
times = 100L,
colsums = colSums(DT[ , !c("A", "B")]),
lapplys = DT[ , lapply(.SD, sum), .SDcols = !c("A", "B")]
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# colsums 1624.2622 2020.9064 2028.9546 2034.3191 2049.9902 2140.8962 100
# lapplys 246.5824 250.3753 252.9603 252.1586 254.8297 266.1771 100

关于r - 在 data.table R 中使用 lapply .SD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32276887/

27 4 0