web-dev-qa-db-ja.com

データフレーム列を名前でドロップする

データフレームから削除したい列がいくつかあります。次のような方法で個別に削除できることを私は知っています。

df$x <- NULL

しかし、私はもっと少ないコマンドでこれをしたいと思っていました。

また、次のように整数のインデックスを使用して列を削除できることもわかっています。

df <- df[ -c(1, 3:6, 12) ]

しかし、私は私の変数の相対位置が変わるかもしれないことを心配しています。

Rがどれほど強力であるかを考えると、私は各列を一つずつドロップするよりも良い方法があるかもしれないと考えました。

759
Btibert3

簡単な名前のリストを使うことができます。

DF <- data.frame(
  x=1:10,
  y=10:1,
  z=rep(5,10),
  a=11:20
)
drops <- c("x","z")
DF[ , !(names(DF) %in% drops)]

あるいは、それらのリストを作成して保存し、それらを名前で参照することもできます。

keeps <- c("y", "a")
DF[keeps]

編集:まだインデックス関数のdrop引数に精通していないそれらのために、あなたがデータフレームとして1つのカラムを保持したいならば、あなたはします:

keeps <- "y"
DF[ , keeps, drop = FALSE]

drop=TRUE(または言及していない)は、不要な次元を削除するので、列yの値を持つベクトルを返します。

811
Joris Meys

subsetコマンドもあります。どの列が必要かがわかっている場合に便利です。

df <- data.frame(a = 1:10, b = 2:11, c = 3:12)
df <- subset(df, select = c(a, c))

@hadleyによるコメントの後に更新されました: drop columns a、cにあなたができること:

df <- subset(df, select = -c(a, c))
395
within(df, rm(x))

おそらく最も簡単です、または複数の変数の場合:

within(df, rm(x, y))

あるいはdata.tablesを扱っているのであれば( data.tableの名前で列を削除するにはどうすればいいですか? ):

dt[, x := NULL]   # Deletes column x by reference instantly.

dt[, !"x"]   # Selects all but x into a new data.table.

または複数の変数の場合

dt[, c("x","y") := NULL]

dt[, !c("x", "y")]
150
Max Ghenis

このように%in%を使うことができます:

df[, !(colnames(df) %in% c("x","bar","foo"))]
101
Joshua Ulrich

list(NULL)でも動作します。

dat <- mtcars
colnames(dat)
# [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
# [11] "carb"
dat[,c("mpg","cyl","wt")] <- list(NULL)
colnames(dat)
# [1] "disp" "hp"   "drat" "qsec" "vs"   "am"   "gear" "carb"
44
Vincent

Grep()が数値ベクトルを返すという事実に基づく、より強力な戦略があります。私のデータセットの1つで行ったように変数のリストが長い場合は、「。A」で終わる変数と「.B」で終わる変数があり、「。A」で終わる変数のみが必要ですどちらのパターンとも一致しないすべての変数で、これを行います。

dfrm2 <- dfrm[ , -grep("\\.B$", names(dfrm)) ]

当面のケースでは、Joris Meysの例を使用すると、それほどコンパクトではない可能性がありますが、次のようになります。

DF <- DF[, -grep( paste("^",drops,"$", sep="", collapse="|"), names(DF) )]
37
42-

参照によって列を削除し、data.framesに関連する内部コピーを避けたい場合は、data.tableパッケージと関数:=を使用できます。

:=演算子の左側に文字ベクトル名を渡し、RHSとしてNULLを渡すことができます。

library(data.table)

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)
# or more simply  DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10) #

DT[, c('a','b') := NULL]

[の呼び出しの外側で名前を文字ベクトルとして事前定義したい場合は、オブジェクトの名前を()または{}でラップして、LHSがDTのスコープ内の名前としてではなく呼び出しスコープ内で評価されるようにします。

del <- c('a','b')
DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, (del) := NULL]
DT <-  <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, {del} := NULL]
# force or `c` would also work.   

setを使うこともできます。これは[.data.table のオーバーヘッドを避け、data.framesでも機能します。

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)

# drop `a` from df (no copying involved)

set(df, j = 'a', value = NULL)
# drop `b` from DT (no copying involved)
set(DT, j = 'b', value = NULL)
37
mnel

もう一つのdplyr答え。変数に共通の命名構造がある場合は、starts_with()を試してください。例えば

library(dplyr)
df <- data.frame(var1 = rnorm(5), var2 = rnorm(5), var3 = rnorm (5), 
                 var4 = rnorm(5), char1 = rnorm(5), char2 = rnorm(5))
df
#        var2      char1        var4       var3       char2       var1
#1 -0.4629512 -0.3595079 -0.04763169  0.6398194  0.70996579 0.75879754
#2  0.5489027  0.1572841 -1.65313658 -1.3228020 -1.42785427 0.31168919
#3 -0.1707694 -0.9036500  0.47583030 -0.6636173  0.02116066 0.03983268
df1 <- df %>% select(-starts_with("char"))
df1
#        var2        var4       var3       var1
#1 -0.4629512 -0.04763169  0.6398194 0.75879754
#2  0.5489027 -1.65313658 -1.3228020 0.31168919
#3 -0.1707694  0.47583030 -0.6636173 0.03983268

データフレーム内の一連の変数を削除したい場合は、:を使用できます。たとえば、var2var3、および all の間の変数を削除したい場合は、var1を残すだけです。

df2 <- df1 %>% select(-c(var2:var3) )  
df2
#        var1
#1 0.75879754
#2 0.31168919
#3 0.03983268
22
Pat W.

興味深いことに、これはRの奇妙な複数の構文の不一致の1つにフラグを立てます。たとえば、2列のデータフレームがあるとします。

df <- data.frame(x=1, y=2)

これはデータフレームを与える

subset(df, select=-y)

しかしこれはベクトルを与える

df[,-2]

これはすべて?[で説明されていますが、それは必ずしも予期された動作ではありません。少なくとも私には違います。

20
jkeirstead
DF <- data.frame(
  x=1:10,
  y=10:1,
  z=rep(5,10),
  a=11:20
)
DF

出力:

    x  y z  a
1   1 10 5 11
2   2  9 5 12
3   3  8 5 13
4   4  7 5 14
5   5  6 5 15
6   6  5 5 16
7   7  4 5 17
8   8  3 5 18
9   9  2 5 19
10 10  1 5 20

DF[c("a","x")] <- list(NULL)

出力:

        y z
    1  10 5
    2   9 5
    3   8 5
    4   7 5
    5   6 5
    6   5 5
    7   4 5
    8   3 5    
    9   2 5
    10  1 5
19
Kun Ren

他の可能性:

df <- df[, setdiff(names(df), c("a", "c"))]

または

df <- df[, grep('^(a|c)$', names(df), invert=TRUE)]
19
scentoni

これを実行するためのdplyrの方法は次のとおりです。

#df[ -c(1,3:6, 12) ]  # original
df.cut <- df %>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)  # with dplyr::select()

注釈なしで読み、理解するのが直感的であり、データフレーム内の位置を変更する列に対してロバストであるため、これが好きです。また、-を使用して要素を削除するベクトル化イディオムに従います。

18
c.gutierrez

Dplyr Solution

ここではあまり注意を向けないでしょうが、削除したい列のリストがあり、それをdplyrチェーンで実行したい場合は、select節でone_of()を使用します。

これは簡単で再現可能な例です。

undesired <- c('mpg', 'cyl', 'hp')

mtcars <- mtcars %>%
  select(-one_of(undesired))

ドキュメントは?one_ofを実行するか、またはここにあります。

http://genomicsclass.github.io/book/pages/dplyr_tutorial.html

16
User632716

私はもっ​​と良い慣用句があるはずだと考え続けていますが、名前による列の減算のために、私は以下をする傾向があります:

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)

# return everything except a and c
df <- df[,-match(c("a","c"),names(df))]
df
12
JD Long

Bernd BischlのBBmiscパッケージにはdropNamed()という名前の関数があります。

BBmisc::dropNamed(df, "x")

利点は、データフレーム引数を繰り返すのを避け、(magrittrのアプローチと同じように)dplyrをパイプ処理するのに適していることです。

df %>% BBmisc::dropNamed("x")
11
krlmlr

上記の@ hadleyを使用したくない場合の別の解決策: "COLUMN_NAME"が削除したい列の名前である場合:

df[,-which(names(df) == "COLUMN_NAME")]
7
Nick Keramaris

以前の回答で示したselect(-one_of(drop_col_names))以外にも、select()を使用して列を削除するためのdplyrオプションがいくつかあります。これには、特定の列名をすべて定義する必要はありません。

library(dplyr)
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 
5
sbha

削除するには、 データフレーム と、 カンマ区切りの名前 の文字列を指定します。

remove_features <- function(df, features) {
  rem_vec <- unlist(strsplit(features, ', '))
  res <- df[,!(names(df) %in% rem_vec)]
  return(res)
}

使用方法

remove_features(iris, "Sepal.Length, Petal.Width")

enter image description here

3
Cybernetic

whichを使用して、削除したい列のインデックスを見つけます。これらのインデックスに負の符号(*-1)を付けます。それから、それらの値をサブセット化して、データフレームからそれらを削除します。これは一例です。

DF <- data.frame(one=c('a','b'), two=c('c', 'd'), three=c('e', 'f'), four=c('g', 'h'))
DF
#  one two three four
#1   a   d     f    i
#2   b   e     g    j

DF[which(names(DF) %in% c('two','three')) *-1]
#  one four
#1   a    g
#2   b    h
1
milan