ベクトルから複数の値を削除する方法は?


125

私は次のようなベクトルを持っています:私は次のようなa = c(1:10)複数の値を削除する必要があります:2, 3, 5

ベクター内のそれらの番号(ベクター内の位置ではありません)を削除するにはどうすればよいですか?

現時点では、ベクトルをループして、次のようなことをしています。

a[!a=NUMBER_TO_REMOVE]

でも自動でやってくれる機能があると思います。

回答:


192

%in%オペレータは、削除するnumersの中である要素を示しています:

> a <- sample (1 : 10)
> remove <- c (2, 3, 5)
> a
 [1] 10  5  2  7  1  6  3  4  8  9
> a %in% remove
 [1] FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
> a [! a %in% remove]
 [1] 10  7  1  6  4  8  9

これにより、比較できないもの(NAまたはなど)が警告なしに削除さInf)れます(ただし、にaリストされていない限り、重複する値は保持されますremove)。

  • aが比較できないものを含むことができるが、含まない場合はremove、を使用してmatch0一致しないものと比較できないものを返すように指示できます(%in%は便利なショートカットですmatch):

    > a <- c (a, NA, Inf)
    > a
     [1]  10   5   2   7   1   6   3   4   8   9  NA Inf
    > match (a, remove, nomatch = 0L, incomparables = 0L)
     [1] 0 3 1 0 0 0 2 0 0 0 0 0
    > a [match (a, remove, nomatch = 0L, incomparables = 0L) == 0L]
    [1]  10   7   1   6   4   8   9  NA Inf

    incomparables = 0比較できないものはとにかく一致しないので必要ありません、読みやすくするために含めます。
    これは、ところで、setdiff内部で行うことです(ただし、にないunique複製を破棄する必要はaありませんremove)。

  • remove比類のないものが含まれている場合は、個別にチェックする必要があります。例:

    if (any (is.na (remove))) 
      a <- a [! is.na (a)]

    (これとは区別さNAれませんNaNが、Rマニュアルはとにかくそれらに違いがあることに頼るべきではないことを警告しています)

    以下のためにInf/ -Infあなたは両方をチェックする必要がありますsignし、is.finite


1
setdiff1つの操作ですべてを行い、修正されたベクトルを1回だけ参照するため、より優れています。
Olexa

1
@Olexa:セットの違いは、特定の数値セットのすべての出現をベクトルから削除することと常に同じaとは限りませんremove。重複していないものも削除されます。それが問題でない場合は、も使用できますsetdiffsetdiff、ところで、用途matchのためには%in%ショートカットです。
cbeleitesがSXに不満

97

使用できますsetdiff

与えられた

a <- sample(1:10)
remove <- c(2, 3, 5)

その後

> a
 [1] 10  8  9  1  3  4  6  7  2  5
> setdiff(a, remove)
[1] 10  8  9  1  4  6  7

1
ときに非常に便利なaあなたは1本のではなく3のラインと、一時変数で物事を行うことができますので、他の関数の結果である
jf328

14
これは%in%、入力ベクトルに重複が含まれている場合(つまり、重複なしでsetdiff一意のセットのみが返される場合)、ソリューションとは異なる結果を生成します
talat

2
@docendodiscimus:fsetdiffdata.tableパッケージにはall、入力ベクトルの重複を維持できるフラグ(デフォルトはF)があります。
Juergen、2018年

9

次のようにして行うことができます。

> x<-c(2, 4, 6, 9, 10) # the list
> y<-c(4, 9, 10) # values to be removed

> idx = which(x %in% y ) # Positions of the values of y in x
> idx
[1] 2 4 5
> x = x[-idx] # Remove those values using their position and "-" operator
> x
[1] 2 6

まもなく

> x = x[ - which(x %in% y)]

1
あなたの例であなたがリストと呼んでいるものはベクトルですよね?
Patrick 2016

はい私はベクトルを意味します。コメントをありがとう。
ykpemre 2016

ここでは必要ありませんwhich。基本的には@cbeleitesの回答と同じです。
David Arenburg 2017年

はい、似ていますが、いくつかの点で異なります。whichTRUE値のインデックスを返します。したがって、マイナス記号は「これらのインデックス以外のインデックス」を表すために使用できます。またwhich、自然言語に近いため読みやすくなります。
ykpemre 2017

4

の代わりに

x <- x[! x %in% c(2,3,5)]

パッケージpurrrとを使用するとmagrittr、次のことができます。

your_vector %<>% discard(~ .x %in% c(2,3,5))

これによりsubset、ベクター名を1回だけ使用できます。そして、あなたはパイプでそれを使うことができます:)


変数名の長さに関する最後のステートメントを説明できますか?なぜあなたはそれが好きではないのですか?なぜ他の方法よりも優れているのですか?または、メインの問題/質問に関連していないため、その段落を削除します。
rodrigoap

2

まず、新しい演算子を定義できます。

"%ni%" = Negate( "%in%" )

次に、そのようなxは削除されません

x <- 1:10
remove <- c(2,3,5)
x <- x[ x %ni% remove ]

または削除に行く理由、直接行く

x <- x[ x %ni% c(2,3,5)]

3
質問では、2、3、および5はベクター内の位置ではないことが明確に示されています。
blakeoft 2015年

1

更新:

上記の回答はすべて、繰り返される値に対しては機能しません。duplicated()述語を使用した@BenBolkerの回答はこれを解決します。

full_vector[!full_vector %in% searched_vector | duplicated(full_vector)]

元の回答: ここに、このための小さな関数を記述します。

exclude_val<-function(full_vector,searched_vector){

      found=c()

      for(i in full_vector){  

        if(any(is.element(searched_vector,i))){
          searched_vector[(which(searched_vector==i))[1]]=NA
        }
        else{
          found=c(found,i)
        }
    }

    return(found)
}

だから、言ってみましょうfull_vector=c(1,2,3,4,1)searched_vector=c(1,2,3)

exclude_val(full_vector,searched_vector)(4,1)を返しますが、上記の答えはだけを返します(4)


1
どうfull_vector[!full_vector %in% searched_vector | duplicated(full_vector)]ですか?
Ben Bolker、2015

?((今何を、私は私の答えを削除するかだけではなく、あなたを表示するように変更しなければならない。@BenBolkerああ私は、述語「重複」ということを知りませんでした
Özgür

@BenBolker、あなたの解決策は間違っています。試してみてください:full_vector = c(1,1,1,2,3); searched_vector = c(1,1,3);- 1, 1, 2正解の代わりに生成されます1, 2
fnl 2015年

ただ、繰り返される値のための可能な、正しい解決策を追加しますremoveif <- function(from, where) { for (i in where) if (i %in% from) {from = from[-match(i, from)]}; from}
FNL

1
q <- c(1,1,2,2,3,3,3,4,4,5,5,7,7)
rm <- q[11]
remove(rm)
q
q[13] = NaN
q
q %in% 7

これにより、ベクトルの13が数値ではない(NAN)に設定されます。これはfalse remove(q [c(11,12,13)])を示します。これを試してみると、除去機能がベクトル番号で機能しないことがわかります。ベクトル全体を削除しますが、単一要素ではない可能性があります。


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