data.tableの名前で列をどのように削除しますか?


194

で「foo」という名前の列を削除するにはdata.frame、次のようにします。

df <- df[-grep('foo', colnames(df))]

ただし、いったんオブジェクトにdf変換されるとdata.table、列を削除するだけの方法はありません。

例:

df <- data.frame(id = 1:100, foo = rnorm(100))
df2 <- df[-grep('foo', colnames(df))] # works
df3 <- data.table(df)
df3[-grep('foo', colnames(df3))] 

しかし、いったんdata.tableオブジェクトに変換されると、これは機能しなくなります。


2
...のdt代わりにdata.tableという名前を付けたほうが明確だったでしょうdf3
PatrickT

回答:


283

次のいずれかを実行するとfoo、data.tableから列が削除されますdf3

# Method 1 (and preferred as it takes 0.00s even on a 20GB data.table)
df3[,foo:=NULL]

df3[, c("foo","bar"):=NULL]  # remove two columns

myVar = "foo"
df3[, (myVar):=NULL]   # lookup myVar contents

# Method 2a -- A safe idiom for excluding (possibly multiple)
# columns matching a regex
df3[, grep("^foo$", colnames(df3)):=NULL]

# Method 2b -- An alternative to 2a, also "safe" in the sense described below
df3[, which(grepl("^foo$", colnames(df3))):=NULL]

data.tableは、次の構文もサポートしています。

## Method 3 (could then assign to df3, 
df3[, !"foo"]  

ただし"foo"df3df3マイナス列のビューを印刷するだけではなく)実際に列を削除したい場合は、"foo"代わりに方法1を使用します。

grep()またはgrepl()に依存するメソッドを使用するpattern="^foo$"場合"foo""fool"およびなどの名前の列"buffoon"(つまりfoo、部分文字列として含む列)も一致させて削除しない場合は、ではなくを設定する必要があることに注意してください。)

安全性の低いオプション、インタラクティブな使用には問題ありません:

次の2つのイディオムも(列の一致が含まれている場合)機能しdf3ますが、一致"foo"しない場合はおそらく予期しない方法で失敗します。たとえば、それらのいずれかを使用して存在しない列を検索"bar"すると、行がゼロのdata.tableになります。

結果として、それらは、たとえば、data.tableからsubstringを含む名前の列を差し引いて表示したいようなインタラクティブな使用に本当に最適です"foo"。プログラミングの目的で(または列df3のコピーからではなく実際に列を削除する場合)、メソッド1、2a、および2bが実際に最適なオプションです。

# Method 4:
df3[, .SD, .SDcols = !patterns("^foo$")]

最後に、を使用するアプローチがありますがwith=FALSEdata.tableこの引数の使用から徐々に移行しているため、これを回避できる場所では推奨されません。ここに表示すると、本当に必要な場合に備えてオプションが存在することがわかります。

# Method 5a (like Method 3)
df3[, !"foo", with=FALSE] 
# Method 5b (like Method 4)
df3[, !grep("^foo$", names(df3)), with=FALSE]
# Method 5b (another like Method 4)
df3[, !grepl("^foo$", names(df3)), with=FALSE]

2
-grep対に関するOPへの私のコメントを参照してください!grepl
ジョシュアウルリッヒ

1
@JoshuaUlrich-良い点。grepl()最初に試しましたが、data.tableカラムは論理ベクトルによってインデックスを付けることができないため、機能しませんでした。しかし、これをでgrepl()ラップすることで機能させることができるwhich()ので、整数ベクトルを返すようになりました。
Josh O'Brien

1
でのインデックス作成については知りませんでしたがdata.table、それをラップするのwhichは賢明です!
Joshua Ulrich

6
私もそのことを知りませんでしたdata.tableFR#1797を追加。しかし、方法1は他の方法より(ほぼ)無限に高速です。方法1は、コピーなしで参照によって列を削除します。どんなサイズのdata.tableでも0.005秒を超えると思いませんか。対照的に、テーブルがRAMの50%に近い場合、削除するものを除いてすべてコピーするため、他のものはまったく機能しない可能性があります。
Matt Dowle、2012

1
@ user3969377文字変数の内容に基づいて列を削除する場合は、単に括弧で囲みます。つまり。df [、(afoo):= NULL]
Dean MacGregor

31

setこれを使用して、[.data.tableループ内のオーバーヘッドを回避することもできます。

dt <- data.table( a=letters, b=LETTERS, c=seq(26), d=letters, e=letters )
set( dt, j=c(1L,3L,5L), value=NULL )
> dt[1:5]
   b d
1: A a
2: B b
3: C c
4: D d
5: E e

列名で実行する場合は、which(colnames(dt) %in% c("a","c","e"))で機能するはずですj


2
ではdata.tableあなたは、列名によってそれをしたい場合は1.11.8、あなたが直接行うことができますrm.col = c("a","b")dt[, (rm.col):=NULL]
ドゥッチョ・A

20

私は単にデータフレームの種類でそれを行うだけです。

DT$col = NULL

高速で、私が見る限り問題はありません。

更新:$<-演算子を使用するとオブジェクトがコピーされるため、DTが非常に大きい場合は最適な方法ではありません。だからもっと使う:

DT[, col:=NULL]

8

データテーブルで削除する個々の列が多く、すべての列名の入力を避けたい場合の非常にシンプルなオプション#careadviced

dt <- dt[, -c(1,4,6,17,83,104)]

代わりに、列番号に基づいて列が削除されます。

data.tableの利点をバイパスするため、明らかに効率的ではありませんが、たとえば500,000行未満で作業している場合はうまく機能します


4

あなたdtが列を持っていると仮定しcol1col2col3col4col5coln

それらのサブセットを削除するには:

vx <- as.character(bquote(c(col1, col2, col3, coln)))[-1]
DT[, paste0(vx):=NULL]

これはコメントであるべきです
Sachila Ranawaka 2017

-2

列名に使用する関数を指定して、列の数をNULLに設定する方法を次に示します。

deleteColsFromDataTable <- function (train, toDeleteColNames) {

       for (myNm in toDeleteColNames)

       train <- train [,(myNm):=NULL]

       return (train)
}


-7

data.tableの場合、列をNULLに割り当てると削除されます。

DT[,c("col1", "col1", "col2", "col2")] <- NULL
^
|---- Notice the extra comma if DT is a data.table

...これは次と同等です:

DT$col1 <- NULL
DT$col2 <- NULL
DT$col3 <- NULL
DT$col4 <- NULL

data.frameに相当するものは次のとおりです。

DF[c("col1", "col1", "col2", "col2")] <- NULL
      ^
      |---- Notice the missing comma if DF is a data.frame

Q. data.tableのバージョンにコンマがあり、data.frameのバージョンにコンマがないのはなぜですか?

A. data.framesは列のリストとして格納されるため、コンマをスキップできます。あなたはまた、しかし、あなたはのリストにそれらを割り当てる必要があります、それを追加することができNULL、S DF[, c("col1", "col2", "col3")] <- list(NULL)


@Arun data.frames行と列が入れ替わる状況は考えられません。それは非論理的でしょう。
duHaas 14年

@Arun私はあなたの最初のコメントがあなたが電話する可能性がある時があったように思われたので私にあなたにタグを付けました、そして私はこれDF[column,row]が実際に起こったインスタンスが実際にあったかどうか見たかっただけです。
duHaas 14年

タイプミスを削除するために回答を更新しました。
Contango 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.