データフレームから削除したい列がいくつかあります。次のような方法で個別に削除できることを私は知っています。
df$x <- NULL
しかし、私はもっと少ないコマンドでこれをしたいと思っていました。
また、次のように整数のインデックスを使用して列を削除できることもわかっています。
df <- df[ -c(1, 3:6, 12) ]
しかし、私は私の変数の相対位置が変わるかもしれないことを心配しています。
Rがどれほど強力であるかを考えると、私は各列を一つずつドロップするよりも良い方法があるかもしれないと考えました。
簡単な名前のリストを使うことができます。
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
の値を持つベクトルを返します。
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))
within(df, rm(x))
おそらく最も簡単です、または複数の変数の場合:
within(df, rm(x, y))
あるいはdata.table
sを扱っているのであれば( 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")]
このように%in%
を使うことができます:
df[, !(colnames(df) %in% c("x","bar","foo"))]
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"
Grep()が数値ベクトルを返すという事実に基づく、より強力な戦略があります。私のデータセットの1つで行ったように変数のリストが長い場合は、「。A」で終わる変数と「.B」で終わる変数があり、「。A」で終わる変数のみが必要ですどちらのパターンとも一致しないすべての変数で、これを行います。
dfrm2 <- dfrm[ , -grep("\\.B$", names(dfrm)) ]
当面のケースでは、Joris Meysの例を使用すると、それほどコンパクトではない可能性がありますが、次のようになります。
DF <- DF[, -grep( paste("^",drops,"$", sep="", collapse="|"), names(DF) )]
参照によって列を削除し、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)
もう一つの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
データフレーム内の一連の変数を削除したい場合は、:
を使用できます。たとえば、var2
、var3
、および all の間の変数を削除したい場合は、var1
を残すだけです。
df2 <- df1 %>% select(-c(var2:var3) )
df2
# var1
#1 0.75879754
#2 0.31168919
#3 0.03983268
興味深いことに、これはRの奇妙な複数の構文の不一致の1つにフラグを立てます。たとえば、2列のデータフレームがあるとします。
df <- data.frame(x=1, y=2)
これはデータフレームを与える
subset(df, select=-y)
しかしこれはベクトルを与える
df[,-2]
これはすべて?[
で説明されていますが、それは必ずしも予期された動作ではありません。少なくとも私には違います。
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
他の可能性:
df <- df[, setdiff(names(df), c("a", "c"))]
または
df <- df[, grep('^(a|c)$', names(df), invert=TRUE)]
これを実行するための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()
注釈なしで読み、理解するのが直感的であり、データフレーム内の位置を変更する列に対してロバストであるため、これが好きです。また、-
を使用して要素を削除するベクトル化イディオムに従います。
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
私はもっと良い慣用句があるはずだと考え続けていますが、名前による列の減算のために、私は以下をする傾向があります:
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
Bernd BischlのBBmisc
パッケージにはdropNamed()
という名前の関数があります。
BBmisc::dropNamed(df, "x")
利点は、データフレーム引数を繰り返すのを避け、(magrittr
のアプローチと同じように)dplyr
をパイプ処理するのに適していることです。
df %>% BBmisc::dropNamed("x")
上記の@ hadleyを使用したくない場合の別の解決策: "COLUMN_NAME"が削除したい列の名前である場合:
df[,-which(names(df) == "COLUMN_NAME")]
以前の回答で示した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
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