2016-06-10 17 views
6

Grup tarafından hesaplanan, bir fonksiyon tarafından döndürülen bir vektörün elemanları için ayrı sütunlara sahip bir data.table üretmek için idiomatic data.table yaklaşımı nedir? fonksiyon range() olduğunutranskript vektörü data.table içinde gruplandırılmıştır

library(data.table) 
data(iris) 
setDT(iris) 

, ben benzer bir çıktı isterdim:

iris[, .(min_petal_width = min(Petal.Width), 
     max_petal_width = max(Petal.Width) 
     ), keyby = Species] # produces desired output 

ama range() işlevini kullanarak

data.table düşünün.

Ben dcast kullanabilirsiniz, ancak o çirkin:

dcast(
    iris[, .(petal_width = range(Petal.Width), 
      value = c("min_petal_width", "max_petal_width")), 
     keyby = Species], 
    Species ~ value, value.var = "petal_width") 

Ben çizgisinde daha basit ifadesi vardır umut ediyorum:

iris[, (c("min_petal_width","max_petal_width")) = range(Petal.Width), 
     keyby = Species] # doesn't work 

cevap

5

Kişisel yaklaşım çok yakındı. Sadece bir listeyi data.table ile beslemeniz gerektiğini ve bunu memnuniyetle kabul edeceğinizi unutmayın. bunlar yerine yeni sütun ekleme sonucunu toplamak istediğinizi olduğundan,

cols <- c("min_petal_width", "max_petal_width") 
iris[, setNames(as.list(range(Petal.Width)), cols), keyby = Species] 

kullanabilirsiniz .. Soru oynanırsa

iris[, c("min_petal_width","max_petal_width") := as.list(range(Petal.Width)), 
    by = Species] 

Ama vardır eminim: Dolayısıyla, kullanabilirsiniz diğer birkaç data.table yaklaşım da var.

+2

Bu yeni bir data.table dönmez, ancak buna – digEmAll

+0

@digEmAll iki sütun ekleme yerinde data.table irisi değiştirir, ah, şu tabii konum. –

6

Ayrıca yapabilirsiniz:

okunabilirliği ve kısalık sizin için gerçekten önemli ise
dt[, lapply(list(min=min, max=max), function(f) f(Petal.Width)), by=Species] 
#  Species min max 
# 1:  setosa 0.1 0.6 
# 2: versicolor 1.0 1.8 
# 3: virginica 1.4 2.5 
2

, ben özel bir işlev veya daha sonra kolayca data.table alt kümesi ifadesinde kullanabilirsiniz ikili operatörü, örneğin tanımlarsınız :

# custom function 
.nm <- function(v,vnames){ 
    `names<-`(as.list(v),vnames) 
} 
# custom binary operator 
`%=%` <- function(vnames,v){ 
    `names<-`(as.list(v),vnames) 
} 

# using custom function 
iris[, .nm(range(Petal.Width),c("min_petal_width", "max_petal_width")), keyby = Species] 

# using custom binary operator 
iris[, c("min_petal_width", "max_petal_width") %=% range(Petal.Width), keyby = Species]