2013-10-18 112 views
6

我有幾個data.tables我想rbindlist。這些表格包含(可能缺失)級別的因素。然後rbindlist(...)do.call(rbind(...))表現不同:rbindlist因素缺失水平

dt1 <- data.table(x=factor(c("a", "b"), levels=letters)) 

rbindlist(list(dt1, dt1))[,x] 
## [1] a b a b 
## Levels: a b 

do.call(rbind, list(dt1, dt1))[,x] 
## [1] a b a b 
## Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z 

如果我想保持水平,我有TOR訴諸rbind還是有data.table方式?

+4

您可以隨時搶水平,你叫'rbindlist'面前,然後把他們回來(見[這裏](http://stackoverflow.com/questions/14634964/how -does酮變化的層次對的一因子列功能於一個數據表))。但我認爲你應該有一個'droplevels = TRUE'的說法。 – Justin

回答

4

我猜rbindlist比較快,因爲它不做的do.call(rbind.data.frame,...)

檢查爲什麼不綁定後設定的水平?

Dt <- rbindlist(list(dt1, dt1)) 
    setattr(Dt$x,"levels",letters) ## set attribute without a copy 

?setattr

SETATTR()是在許多情況下是有用通過參考設置屬性,並且可以一個對象的任何物體或零件上使用,而不只是data.tables。

+0

謝謝。但是我實際使用這個的地方,我不知道水平。如果我有2個'data.tables',我已經需要'unique(unlist(lapply(list(dt1,dt2),function(dt)levels(dt [,x]))))'來找到這些級別,那麼恐怕'do.call(rbind,...)'版本可能會更快。 – shadow

+2

@shadow我猜測只有當行數很多時,纔會有更多的因子水平,在這種情況下,我會問 - 有什麼影響因素?如果使用內部'c.factor'函數,可以加快最後一步的速度,那麼我只會使用因子,如果我有少量元素在數據中重複使用的次數很多 – eddi

+1

fwiw在你的場景中,do.call(data.table ::: c.factor,lapply(list(dt1,dt2),「[[','x'))' – eddi

2

感謝您指出這個問題。由於version 1.8.11已定:

dt1 <- data.table(x=factor(c("a", "b"), levels=letters)) 

rbindlist(list(dt1, dt1))[,x] 
#[1] a b a b 
#Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z