R dplyr:複数の列を削除する


96

ドロップしたいデータフレームとそのデータフレーム内の列のリストがあります。iris例としてデータセットを使用してみましょう。ドロップSepal.LengthSepal.Widthて残りの列のみを使用したいと思います。パッケージを使用して、selectまたはパッケージselect_からこれを行うにはどうすればよいdplyrですか?

これが私がこれまでに試したことです:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
iris %>% select(-drop.cols)

-drop.colsのエラー:単項演算子の引数が無効です

iris %>% select_(.dots = -drop.cols)

-drop.colsのエラー:単項演算子の引数が無効です

iris %>% select(!drop.cols)

!drop.colsのエラー:引数タイプが無効です

iris %>% select_(.dots = !drop.cols)

!drop.colsのエラー:引数タイプが無効です

これらはすでに存在しているはずの非常に便利な操作のように見えるので、私は明白な何かを見逃しているように感じます。Githubで誰かが同様の問題を投稿し Hadleyは「負のインデックス作成」を使用すると述べました。それは(私が思うに)私が試みたものですが、無駄です。助言がありますか?

回答:


127

select_varsのヘルプを確認してください。これにより、これを使用する方法についていくつかの追加のアイデアが得られます。

あなたの場合:

iris %>% select(-one_of(drop.cols))

ありがとう。何らかの理由で、これはで機能しますirisが、実際のデータフレームでは機能しません(irisおもちゃの例でした)。データフレームに4558行と147列が含まれています。受け取ったエラーメッセージはでしたError in eval(x$expr, data, x$env) : variable names are limited to 10000 bytes。なぜこれが起こっているのでしょうか?
Navaneethan Santhanam 2016

1
ああ、間違いをしたようです。のselect_vars代わりに誤って使用しましたselect。今では完全に動作します!
Navaneethan Santhanam 2016

5
次のような組み込み関数についてどこで調べるべきone_ofですか?何か不足している場合を除き、パッケージのドキュメント(help(package='dplyr'))には記載されていません。
地質学2016

4
@geotheory、実際にはone_ofが文書化されています。参照してくださいhelp(one_of, package = "dplyr")。少なくとも、パッケージバージョン0.5.0に含まれています。しかし、Hadleyが彼のパッケージの1つに更新がある場合に投稿するブログを読むと役立ちます。そして、いくつかの関数は他の関数の中に文書化されています。残念ながら、そのためにはすべてのドキュメントを読む必要がありますが、ほとんどの場合、関数ではすぐにわかりにくい、または可能ではないものが必要なときに行います。
phiver 2016

10
ありがとう。ドキュメントの観点から、これらの関数について最初にどのようにして見つけますか?
地質学2016


37

超えてselect(-one_of(drop.cols))使用して列を削除するためのカップル他のオプションがあるselect()ことは、すべての特定の列名を定義伴わない(dplyrを使用して、列名にいくつかのより多くの多様性のためのサンプルデータをSTARWARS):

starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  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('^f.+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 

select_if(~!is.list(.))相当しselect_if(is.list(.))ますか?
Jasha

3
この場合~、無名関数を定義するための略語であり、そうでないことを表すもう1つの記号ではありません。たとえば、これら2つは同じことfunction(x) {!is.list(x)}を意味し~!is.list(.)ます。の~省略形と考えてくださいfunction(.)
SlyFox

8

このselect()関数は、dplyrパッケージとMASSパッケージの両方で使用されるため、注意してください。MASSがロードされている場合、select()が正しく機能しない可能性があります。ロードされているパッケージを確認するsessionInfo()には、「その他の添付パッケージ:」セクションに入力して探します。ロードされている場合はdetach( "package:MASS", unload = TRUE )、と入力すると、select()関数が再び機能するようになります。


12
または、パッケージの名前空間で関数に直接アクセスすることもできますdplyr::select()
Triamus 2017

2
私はこの問題に頻繁に出くわしました。今は通常、スクリプトの先頭に新しい関数を定義していますdselect <- dplyr::select()
filups21

5

我々は試すことができます

iris %>% 
      select_(.dots= setdiff(names(.),drop.cols))

@akrunのおかげで、これは完全に機能しました。ただし、dplyr基本的な分析タスクを読み書きしやすくするという周囲の誇大宣伝の機能を考えると、実際の解決策が回避策のように見えるのは残念です。
Navaneethan Santhanam 2016

@NavaneethanSanthanam実際にはone_of、他のソリューションで行く方法です。忘れました。
akrun 2016年

3

別の方法は、不要な列をに変更することですNULL。これにより、埋め込まれた括弧が回避されます。

head(iris,2) %>% mutate_at(drop.cols, ~NULL)
#   Petal.Length Petal.Width Species
# 1          1.4         0.2  setosa
# 2          1.4         0.2  setosa

また、列がない場合でも警告は出されません。
スコズ

3

列名に特殊文字が含まれている場合、selectまたはselect_期待どおりに機能しない可能性があります。このdplyr使用のプロパティ"."。問題のデータセットを参照するには、次の行を使用してこの問題を解決できます。

drop.cols <- c('Sepal.Length', 'Sepal.Width')
  iris %>% .[,setdiff(names(.),drop.cols)]

コードのみの回答はお勧めしません。回答がどのように機能するか、および既存の回答とどのように異なるのかについて説明してください。
ラルフスタブナー、

ありがとうございました!!上記の他のソリューションは、この正確な理由で機能しませんでした。
Marty999

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