簡體   English   中英

拆分data.table

[英]split data.table

我有一個data.table,我想分成兩個。 我這樣做如下:

dt <- data.table(a=c(1,2,3,3),b=c(1,1,2,2))
sdt <- split(dt,dt$b==2)

但如果我想將這樣的事情作為下一步

sdt[[1]][,c:=.N,by=a]

我收到以下警告信息。

警告消息:在[.data.table (sdt [[1]] ,, := (c,.N),by = a):通過獲取整個表的副本檢測並修復無效的.internal.selfref,所以that:=可以通過引用添加此新列。 在較早的時候,這個data.table已經被R復制了。避免鍵< - ,名稱< - 和attr < - 當前(並且奇怪地)在R中可以復制整個data.table。 使用set *語法來避免復制:setkey(),setnames()和setattr()。 此外,list(DT1,DT2)將復制整個DT1和DT2(R的list()復制命名對象),如果需要(將被實現)使用reflist()。 如果此消息沒有幫助,請向datatable-help報告,以便修復根本原因。

只是想知道是否有更好的方法來分割表,以便它更有效(並且不會得到這個消息)?

這適用於v1.8.7(也可能在v1.8.6中工作):

> sdt = lapply(split(1:nrow(dt), dt$b==2), function(x)dt[x])
> sdt
$`FALSE`
   a b
1: 1 1
2: 2 1

$`TRUE`
   a b
1: 3 2
2: 3 2

> sdt[[1]][,c:=.N,by=a]     # now no warning
> sdt
$`FALSE`
   a b c
1: 1 1 1
2: 2 1 1

$`TRUE`
   a b
1: 3 2
2: 3 2

但是,正如@mnel所說,這是低效的。 如果可能,請避免分裂。

我正在尋找一些方法來對data.table進行拆分,我遇到了這個老問題。

有時你需要做一個分割,而data.table“by”方法並不方便。

實際上,您可以輕松地使用data.table指令進行拆分,並且它非常有效:

SplitDataTable <- function(dt,attr) {
  boundaries=c(0,which(head(dt[[attr]],-1)!=tail(dt[[attr]],-1)),nrow(dt))
  return(
    mapply(
      function(start,end) {dt[start:end,]},
      head(boundaries,-1)+1,
      tail(boundaries,-1),
      SIMPLIFY=F))
}

如上所述(@jangorecki),包data.table已經有了自己的拆分功能。 在這個簡化的案例中我們可以使用:

> dt <- data.table(a = c(1, 2, 3, 3), b = c(1, 1, 2, 2))
> split(dt, by = "b")
$`1`
   a b
1: 1 1
2: 2 1

$`2`
   a b
1: 3 2
2: 3 2

對於更困難/具體的情況,我建議使用by引用函數在data.table中創建一個新變量:=set然后調用函數split 如果您關心性能,請確保始終保留在data.table環境中,例如, dt[, SplitCriteria := (...)]而不是外部計算拆分變量。

暫無
暫無

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

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