web-dev-qa-db-ja.com

ベクトルの* not *に基づいてRデータフレームの列を選択する

私は、Rデータフレーム(またはマトリックス)から列を抽出できることに精通しています。

_df.2 <- df[, c("name1", "name2", "name3")]
_

しかし、_!_または他のツールを使用してリストされた列以外のすべてを選択できますか?

背景については、かなりの数の列ベクトルを持つデータフレームがあり、回避したいと思います。

  • 少数派を削除することができたときに名前の大部分を入力する
  • はるかに短いdf.2 <- df[, c(1,3,5)]を使用すると、.csvファイルが変更されると、番号付けが同じではなくなるため、コードが完全になります。私はRが初めてであり、変更される可能性のある大きなdfに数値ベクトルを使用しないという難しい方法を学んだと思います。

私は試した:

_df.2 <- df[, !c("name1", "name2", "name3")]
df.2 <- df[, !=c("name1", "name2", "name3")]
_

そして、私がこれを入力していたように、これが機能することがわかりました:

_df.2 <- df[, !names(df) %in% c("name1", "name2", "name3")]
_

この最後の方法よりも良い方法はありますか?

38
Hendy

grepの代わりにwhichがあります:

df.2 <- df[, -which(names(df) %in% c("name1", "name2", "name3"))]
27
harkmug

Negative-grepでより一般化できる短い呼び出しを行うことができます。

df.2 <- df[, -grep("^name[1:3]$", names(df) )] 

Grepは数値を返すため、負のベクトルインデックスを使用して列を削除できます。さらに数またはより複雑なパターンを追加できます。

11
42-

dplyr::select()には、特定の列を削除するためのいくつかのオプションがあります。

_library(dplyr)

drop_columns <- c('cyl','disp','hp')
mtcars %>% 
  select(-one_of(drop_columns)) %>% 
  head(2)

              mpg drat    wt  qsec vs am gear carb
Mazda RX4      21  3.9 2.620 16.46  0  1    4    4
Mazda RX4 Wag  21  3.9 2.875 17.02  0  1    4    4
_

特定の列名を除外すると、次の例では列「hp」と列が「qsec」から「gear」までドロップされます。

_mtcars %>% 
  select(-hp, -(qsec:gear)) %>% 
  head(2)

              mpg cyl disp drat    wt carb
Mazda RX4      21   6  160  3.9 2.620    4
Mazda RX4 Wag  21   6  160  3.9 2.875    4
_

contains()starts_with()ends_with()、またはmatches()を無効にすることもできます。

_mtcars %>% 
  select(-contains('t')) %>%
  select(-starts_with('a')) %>% 
  select(-ends_with('b')) %>% 
  select(-matches('^m.+g$')) %>% 
  head(2)

              cyl disp  hp  qsec vs gear
Mazda RX4       6  160 110 16.46  0    4
Mazda RX4 Wag   6  160 110 17.02  0    4
_
6
sbha

古いスレッドですが、別の解決策があります:

df.2 <- subset(df, select=-c(name1, name2, name3))

これは別の同様のスレッドに投稿されました(今のところ見つかりませんが)。説明する状況では持続可能なコードである必要があり、おそらく他のオプションよりも読みやすく、編集しやすいでしょう。

2
mfloren

データを操作するために独自の用途で使用している場合、これを行うカスタム関数を作成できます。私はこのようなことをするかもしれません:

rm.col <- function(df, ...) {
    x <- substitute(...())
    z <- Trim(unlist(lapply(x, function(y) as.character(y))))
    df[, !names(df) %in% z]
}

rm.col(mtcars, hp, mpg)

最初の引数はデータフレーム名です。以下 ...は、削除する列の名前です。

2
Tyler Rinker

私の頭に浮かぶ最も簡単な方法:

filtered_df <-df [、setdiff(names(df)、c( "name1"、 "name2")]

基本的に、列名の完全なリストと除外するサブセット(上記のname1およびname2)のセットの差を計算しています。

0
Ahmed Osman