web-dev-qa-db-ja.com

削除する行の複数の論理条件によるデータフレームのサブセット化

新しいデータフレームに保持する行not!)を指定して、データフレームをサブセット化(フィルター)したいと思います。簡単なサンプルデータフレームを次に示します。

data
v1 v2 v3 v4
a  v  d  c
a  v  d  d
b  n  p  g
b  d  d  h    
c  k  d  c    
c  r  p  g
d  v  d  x
d  v  d  c
e  v  d  b
e  v  d  c

たとえば、列v1の行に「b」、「d」、または「e」がある場合、その観測行を削除して、次のデータフレームを生成します。

v1 v2 v3 v4
a  v  d  c
a  v  d  d
c  k  d  c    
c  r  p  g

一度に1つの条件に基づいてサブセット化することに成功しています。たとえば、ここでv1に「b」が含まれる行を削除します。

sub.data <- data[data[ , 1] != "b", ]

ただし、このような条件は非常に多いため、一度に1つずつ実行することは望ましくありません。私は以下で成功していません:

sub.data <- data[data[ , 1] != c("b", "d", "e")

または

sub.data <- subset(data, data[ , 1] != c("b", "d", "e"))

!%in%のような他のこともいくつか試しましたが、それは存在しないようです。何か案は?

37
Jota

!は、ステートメントの外側に配置する必要があります。

data[!(data$v1 %in% c("b", "d", "e")), ]

  v1 v2 v3 v4
1  a  v  d  c
2  a  v  d  d
5  c  k  d  c
6  c  r  p  g
39
Andrie

これを試して

subset(data, !(v1 %in% c("b","d","e")))
46
chl

また、&をインクルードしてステートメントを分離することにより、物事を個別の論理ステートメントに分割することでこれを達成することもできます。

subset(my.df, my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e")

これはエレガントではなく、より多くのコードを必要としますが、新しいRユーザーにとっては読みやすいかもしれません。上記のコメントで指摘したように、subsetは対話型で作業するときに最も便利な「便利な」関数です。

10
N Brouwer
data <- data[-which(data[,1] %in% c("b","d","e")),]
5
paul c

この答えは、方法ではなく、理由を説明するためのものです。 Rの'=='演算子は、'+'演算子と同じ方法でベクトル化されます。要素ごとに、左側にあるものの要素を、右側にあるものの要素に一致させます。例えば:

> 1:3 == 1:3
[1] TRUE TRUE TRUE

ここで、最初のテストは1==1(TRUE)、2番目の2==2、3番目の3==3です。順序が間違っているため、これが最初と2番目の要素でFALSEを返すことに注意してください。

> 3:1 == 1:3
[1] FALSE  TRUE FALSE

1つのオブジェクトが他のオブジェクトよりも小さい場合、小さいオブジェクトが大きいオブジェクトと一致するのに必要なだけ繰り返されます。大きいオブジェクトのサイズが小さいオブジェクトのサイズの乗算でない場合、すべての要素が繰り返されないという警告が表示されます。例えば:

>  1:2 == 1:3
[1]  TRUE  TRUE FALSE
Warning message:
In 1:2 == 1:3 :
  longer object length is not a multiple of shorter object length

ここでは、左側が小さいため、最初の一致は1==1、次に2==2、最後に1==3(FALSE)です。側面の1つが1つの要素のみの場合、それが繰り返されます。

> 1:3 == 1
[1]  TRUE FALSE FALSE

要素がベクトル内にあるかどうかをテストするための正しい演算子は、実際に'%in%'であり、左要素のみにベクトル化されます(左ベクトル内の各要素について、右要素内のオブジェクトの一部であるかどうかがテストされます) 。

または、'&'を使用して2つの論理ステートメントを組み合わせることができます。 '&'は2つの要素を取り、両方がTRUEの場合に要素ごとにチェックします。

> 1:3 == 1 & 1:3 != 2
[1]  TRUE FALSE FALSE
4
Sacha Epskamp
my.df <- read.table(textConnection("
v1 v2 v3 v4
a  v  d  c
a  v  d  d
b  n  p  g
b  d  d  h    
c  k  d  c    
c  r  p  g
d  v  d  x
d  v  d  c
e  v  d  b
e  v  d  c"), header = TRUE)

my.df[which(my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e" ), ]

  v1 v2 v3 v4
1  a  v  d  c
2  a  v  d  d
5  c  k  d  c
6  c  r  p  g
3
Roman Luštrik

そしてまた

library(dplyr)
data %>% filter(!v1 %in% c("b", "d", "e"))

または

data %>% filter(v1 != "b" & v1 != "d" & v1 != "e")

または

data %>% filter(v1 != "b", v1 != "d", v1 != "e")

&演算子はコンマによって暗黙指定されます。

1
Joe
_sub.data<-data[ data[,1] != "b"  & data[,1] != "d" & data[,1] != "e" , ]
_

大きくても理解しやすい(推測)であり、!is.na( data[,1])であっても複数の列で使用できます。

1
Hernan