Rのdata.frameから列全体を削除する


267

Rのdata.frameから列全体を削除する方法を知っている人はいますか?たとえば、このdata.frameが与えられた場合:

> head(data)
   chr       genome region
1 chr1 hg19_refGene    CDS
2 chr1 hg19_refGene   exon
3 chr1 hg19_refGene    CDS
4 chr1 hg19_refGene   exon
5 chr1 hg19_refGene    CDS
6 chr1 hg19_refGene   exon

2列目を削除します。


回答:


414

に設定できNULLます。

> Data$genome <- NULL
> head(Data)
   chr region
1 chr1    CDS
2 chr1   exon
3 chr1    CDS
4 chr1   exon
5 chr1    CDS
6 chr1   exon

コメントで指摘されているように、他にもいくつかの可能性があります。

Data[2] <- NULL    # Wojciech Sobala
Data[[2]] <- NULL  # same as above
Data <- Data[,-2]  # Ian Fellows
Data <- Data[-2]   # same as above

次の方法で複数の列を削除できます。

Data[1:2] <- list(NULL)  # Marek
Data[1:2] <- NULL        # does not work!

ただし、最終的にベクトルになる可能性があるため、matrix-subsettingには注意してください。

Data <- Data[,-(2:3)]             # vector
Data <- Data[,-(2:3),drop=FALSE]  # still a data.frame

48
または、次のデータを使用できます。データ<-データ[、-2]
イアンフェロー2011年

2
コンマを使用して、「ドロップ」引数を制御することもできます。これは、FALSEの場合、結果が1列のみで構成されている場合、data.frameがdata.frameのままであることを意味します。コンマなしでは、複数の列が常に左または1つ-ドロップは[-2]抽出では無視されます
mdsumner

3
@mdsumner Data[-2]drop引数を必要としないため、常にdata.frameから戻りdata.frameます。そして、これはローカライズされた列(および列のみ)をdata.frame(より高速に)ローカライズするためのはるかに優れた方法だと思います。チェック:cars[-1](1列data.frame)以上cars[-(1:2)]data frame with 0 columns and 50 rows
Marek

1
また、Data [2] <
-NULL

11
マイナーなヒント:複数の列を削除するData[c(1,2)]<-list(NULL)必要がある場合。
Marek

69

1つ以上の列を名前で削除するには、列名がわかっている場合(実行時に決定されるのではなく)、subset()構文が好きです。たとえば、データフレーム

df <- data.frame(a=1:3, d=2:4, c=3:5, b=4:6)

aあなたができる列だけを削除するには

Data <- subset( Data, select = -a )

そして、あなたができるbd列を削除するには

Data <- subset( Data, select = -c(d, b ) )

あなたは間のすべての列を削除することができますdし、bで。

Data <- subset( Data, select = -c( d : b )

上で述べたように、この構文は列名がわかっている場合にのみ機能します。列名がプログラムで決定されている(つまり、変数に割り当てられている)場合は機能しません。?subsetドキュメントからこの警告を再現します:

警告:

これは、インタラクティブに使用するための便利な関数です。プログラミングには、 '['のような標準のサブセット化関数を使用することをお勧めします。特に、引数 'subset'の非標準の評価は、予期しない結果をもたらす可能性があります。


26

(完全を期すために)名前で列を削除したい場合、これを行うことができます:

cols.dont.want <- "genome"
cols.dont.want <- c("genome", "region") # if you want to remove multiple columns

data <- data[, ! names(data) %in% cols.dont.want, drop = F]

含めるdrop = Fことにより、data.frame列が1つだけ残っている場合でも、結果が確実に均一になります。


22

data.framesを使用する場合、投稿された回答は非常に優れています。ただし、これらのタスクは、メモリの観点からはかなり非効率的です。大きなデータでは、列の削除に非常に長い時間がかかるか、out of memoryエラーが原因で失敗する可能性があります。パッケージdata.tableは、:=オペレーターがこの問題に対処するのに役立ちます。

library(data.table)
> dt <- data.table(a = 1, b = 1, c = 1)
> dt[,a:=NULL]
     b c
[1,] 1 1

違いを示すために、もっと大きな例をまとめる必要があります。この回答は、随時更新します。


3
このdata.table::set関数をdata.frames で使用して、コピーを作成せずに列を即座に削除または変更できます。こちらをご覧ください
GSee

8

1つ以上の列dplyr::select()といくつかのヘルパー関数を削除するためのいくつかのオプションがあります。ヘルパー関数は、ドロップする特定の列すべてに名前を付ける必要がないものがあるため、役立ちます。select()を使用して列をドロップするには、先頭に-するには、列名を否定するためにを。

dplyr::starwarsさまざまな列名のサンプルデータを使用する:

library(dplyr)

starwars %>% 
  select(-height) %>%                  # a specific column name
  select(-one_of('mass', 'films')) %>% # any columns named in one_of()
  select(-(name:hair_color)) %>%       # the range of columns from 'name' to 'hair_color'
  select(-contains('color')) %>%       # any column name that contains 'color'
  select(-starts_with('bi')) %>%       # any column name that starts with 'bi'
  select(-ends_with('er')) %>%         # any column name that ends with 'er'
  select(-matches('^v.+s$')) %>%       # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%          # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

列番号でドロップすることもできます。

starwars %>% 
  select(-2, -(4:10)) # column 2 and columns 4 through 10

すばらしい答えです。(上記で提案したような列名ではなく)その行のいずれかに特定の値を含む列を削除する方法に関するアイデアはありますか?
Laura K

df [、-which(sapply(df、function(x)any(x == a)))]、ここでdfはデータフレームで、aは特定の値です。例:mtcars [、-which(sapply(mtcars、 function(x)any(x == 4)))]
Nanami

7

これにより、を削除して別のにcolumn保存できます。variablevariable

df = subset(data, select = -c(genome) )
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.