2016-09-01 9 views
8

私は数値と文字の両方の変数に作用するこの2段階プロセスdata.tableを単純化しようとしています。例えば。 - 数字変数のそれぞれのtextvarsumの最初の要素を取る。この小さな例を考えてみましょう:data.table数値とテキストの変数を別々にグループ化する

library(data.table) 
dt <- data.table(grpvar=letters[c(1,1,2)], textvar=c("one","two","one"), 
       numvar=1:3, othernum=2:4) 
dt 
# grpvar textvar numvar othernum 
#1:  a  one  1  2 
#2:  a  two  2  3 
#3:  b  one  3  4 

今私の最初に考えたのはlapplyコールのうちの一つの変数を削除するには巣.SDにいたが、私はそれは少し複雑だと思った:

dt[, c(textvar=textvar[1], .SD[, lapply(.SD, sum), .SDcols=-c("textvar")]), by=grpvar] 
# grpvar textvar numvar othernum 
#1:  a  one  3  5 
#2:  b  one  3  4 

それから私は思いました多分私は、それぞれ個別にグループ化を行うと、それらを結合、それはさらに悪いようだ可能性:

dt[, .(textvar=textvar[1]), by=grpvar][ 
    dt[, lapply(.SD, sum), by=grpvar, .SDcols=-c("textvar")], on="grpvar" 
] 
# grpvar textvar numvar othernum 
#1:  a  one  3  5 
#2:  b  one  3  4 

は周りになるだろう単純な構造があります.SDのネスティングまたは参加?私は何か初心者を見下ろすような気がする。

答えて

9

のデータテーブルjは、(意図的に)非常に柔軟です。

は限りjリストを返すよう、リストの各要素が結果data.tableの列になるだろう:私たちは覚えておく必要があるのはということです。 c(list, list)listであるという事実を使用して

次のように、私たちは、表現を構築することができます

dt[, c(textvar = textvar[1L], lapply(.SD, sum)), # select/compute all cols necessary 
     .SDcols = numvar:othernum,     # provide .SD's columns 
     by = grpvar]        # group by 'grpvar' 
# grpvar textvar numvar othernum 
# 1:  a  one  3  5 
# 2:  b  one  3  4 

をここでtextvar[1L] = 1つのベクトルの長さを返すために、私はlist()との最初の式を巻いていませんでしたすなわち、identical(c(1, list(2, 3)), c(list(1), list(2,3)))TRUEです。

v1.9.7からのみ可能です。このバグは、現在の開発版では最近修正されました。

+0

私は1.9.6になっており、後ほどアップグレードする立場にはいないが、すぐにお返事いただきありがとうございます。だから1.9.7は、 "オブジェクト 'textvar' not found"エラーを避けるでしょうか? – thelatemail

+0

@thelatemail、はい。これは、このリリースで最終的に修正することができた長い間の(そして迷惑な)エラーでした。[#495](https://github.com/Rdatatable/data.table/issues/495)。 – Arun

+1

awesome、聞いて良かった:-) – thelatemail

関連する問題