簡體   English   中英

在 data.table R 中使用 lapply.SD

[英]Use of lapply .SD in data.table R

我不太清楚.SDby使用。

例如,下面的代碼片段是否意味着:“將DT中的所有列更改為除AB之外的因子?” 它還在data.table手冊中說:“ .SD指的是每個組的data.table的子集(不包括分組列)” - 所以列AB被排除在外?

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

但是,當您進行聚合時,我也通過 SQL 中的“分組依據”之類by方式閱讀了它。 例如,如果我想對除AB之外的所有列求和(如 SQL 中的colsum ),我是否仍使用類似的東西? 或者在這種情況下,下面的代碼是否意味着對A列和B列中的值進行求和和分組? (像在 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非常重要。 返回的對象是一個data.table ,並且DT中的所有列都與運行代碼之前完全一樣。

  • 您提到要更改列類型

再次參考上面的觀點,請注意您的代碼( DT[, lapply(.SD, as.factor)] )返回一個data.table並且根本不更改DT 一種(不正確的)方法是用base中的data.frame s 完成此操作,即用您返回的新data.table覆蓋舊data.table ,即DT = DT[, lapply(.SD, as.factor)]

這是一種浪費,因為它涉及創建DT的副本,當DT很大時,這可能會成為效率殺手。 解決此問題的正確data.table方法是使用`:=`通過引用更新列,例如DT[, names(DT):= lapply(.SD, as.factor)] ,這不會創建您的副本數據。 有關更多信息,請參閱data.table的參考語義小插圖

  • 您提到了將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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM