2012-07-27 10 views
88

data.table kullanarak birden çok sütuna atamanın en iyi yolu nedir? Örneğin:Birden çok sütun atama: = data.table, grubuna göre

f <- function(x) {c("hi", "hello")} 
x <- data.table(id = 1:10) 

ben böyle bir şey yapmak istiyorum (tabii bu sözdizimi yanlıştır):

x[ , (col1, col2) := f(), by = "id] 

Ve ben bir değişkende adlarla sayıda sütun olabileceğini genişletmek için (diyelim column_names) ve ben yapmak istiyorum:

x[ , col_names := another_f(), by = "id", with = FALSE] 

böyle bir şey yapmak için doğru yolu nedir?

+1

Bu yanıtlandı benziyor: http://stackoverflow.com/questions/11308754/add-multiple-columns-to-r-data- tablo-in-one-fonksiyon çağrısı – Alex

+0

Alex, Bu cevap yakın ama 'by' ile birlikte çalışmış gibi görünmüyor. [FR # 2120] 'ye (https://r-forge.r-project.org/tracker/index.php?func=detail&aid=2120&group_id=240&atid=978) eklediğiniz soruna bağlantı "LHS için = FALSE ile uğraşmaya gerek yok" of: = ", bu yüzden tekrar ziyarete unutulmayacak. –

cevap

106

Bu, şimdi R-Forge'da v1.8.3'te çalışır. Vurguladığın için teşekkürler!

x <- data.table(a = 1:3, b = 1:6) 
f <- function(x) {list("hi", "hello")} 
x[ , c("col1", "col2") := f(), by = a][] 
# a b col1 col2 
# 1: 1 1 hi hello 
# 2: 2 2 hi hello 
# 3: 3 3 hi hello 
# 4: 1 4 hi hello 
# 5: 2 5 hi hello 
# 6: 3 6 hi hello 

x[ , c("mean", "sum") := list(mean(b), sum(b)), by = a][] 
# a b col1 col2 mean sum 
# 1: 1 1 hi hello 2.5 5 
# 2: 2 2 hi hello 3.5 7 
# 3: 3 3 hi hello 4.5 9 
# 4: 1 4 hi hello 2.5 5 
# 5: 2 5 hi hello 3.5 7 
# 6: 3 6 hi hello 4.5 9 

mynames = c("Name1", "Longer%") 
x[ , (mynames) := list(mean(b) * 4, sum(b) * 3), by = a] 
#  a b col1 col2 mean sum Name1 Longer% 
# 1: 1 1 hi hello 2.5 5 10  15 
# 2: 2 2 hi hello 3.5 7 14  21 
# 3: 3 3 hi hello 4.5 9 18  27 
# 4: 1 4 hi hello 2.5 5 10  15 
# 5: 2 5 hi hello 3.5 7 14  21 
# 6: 3 6 hi hello 4.5 9 18  27 


x[ , mynames := list(mean(b) * 4, sum(b) * 3), by = a, with = FALSE][] # same 
# a b col1 col2 mean sum Name1 Longer% 
# 1: 1 1 hi hello 2.5 5 10  15 
# 2: 2 2 hi hello 3.5 7 14  21 
# 3: 3 3 hi hello 4.5 9 18  27 
# 4: 1 4 hi hello 2.5 5 10  15 
# 5: 2 5 hi hello 3.5 7 14  21 
# 6: 3 6 hi hello 4.5 9 18  27 

x[ , get("mynames") := list(mean(b) * 4, sum(b) * 3), by = a][] # same 
# a b col1 col2 mean sum Name1 Longer% 
# 1: 1 1 hi hello 2.5 5 10  15 
# 2: 2 2 hi hello 3.5 7 14  21 
# 3: 3 3 hi hello 4.5 9 18  27 
# 4: 1 4 hi hello 2.5 5 10  15 
# 5: 2 5 hi hello 3.5 7 14  21 
# 6: 3 6 hi hello 4.5 9 18  27 

x[ , eval(mynames) := list(mean(b) * 4, sum(b) * 3), by = a][] # same 
# a b col1 col2 mean sum Name1 Longer% 
# 1: 1 1 hi hello 2.5 5 10  15 
# 2: 2 2 hi hello 3.5 7 14  21 
# 3: 3 3 hi hello 4.5 9 18  27 
# 4: 1 4 hi hello 2.5 5 10  15 
# 5: 2 5 hi hello 3.5 7 14  21 
# 6: 3 6 hi hello 4.5 9 18  27 
+0

Bu cevap ve örnekler için teşekkürler. Her satır için iki sütun, iki satırlı bir sütun yerine, loş çıkıştan iki sütun almak için aşağıdaki satırı nasıl değiştirmeliyim? data.table (objectName = ls()) [, c ("satır", "cols"): = dim (get (objectName)), by = objectName] '(data.table' 1.8 kullanıyorum. 11) – dnlbrky

+0

@dnlbrky 'dim' bir vektör döndürür, bu yüzden 'list' yazarak onu döndürmelidir; Örneğin. '[C ("satır", "sütunlar") = as.list (dim (olsun (ObjectName))), = objectNa tarafından me] '. Sorun, "as.list" ünitesinin genel gider ve küçük vektörü kopyalamasıdır. Verimlilik, grup sayısı arttıkça bir problemse, lütfen bize bildirin. –

+0

Teşekkürler @Matt_Dowle. Ben 'list' denedim ama 'as.list' denedim. Hız bir sorun değil. Sadece çevrede belirli sayıda sütun veya satır bulunan nesneleri bulmanın hızlı bir yolunu istedim. Bu konu dışı, ama ... 'table() 'için NCOL ekleme hakkında ne düşünüyorsunuz? – dnlbrky