벡터에서 여러 값을 삭제하는 방법은 무엇입니까?


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.

  • 경우 aincomparables을 포함 할 수 있지만 remove하지 않을 것이다, 우리가 사용할 수있는 match반환을 말하고, 0비 일치와 incomparables 위해 ( %in%conventient의 바로 가기입니다 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비교할 수없는 것이 어쨌든 일치 하지 않기 때문에 필요 하지 않지만 가독성을 위해 포함시킬 것입니다.
    이것은 btw., setdiff내부적으로 수행하는 것입니다 (그러나에없는 unique복제물은 버리지 a않습니다 remove).

  • remove비교할 수없는 것이 포함 된 경우 개별적으로 확인해야합니다 (예 :

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

    (이것은 구분하지 않습니다 NA에서 NaN하지만 R 매뉴얼 어쨌든 그들 사이의 차이를있는에 한 의존하지해야한다는 경고)

    위해 Inf/ -Inf당신이 모두를 확인해야 sign하고is.finite


1
setdiff한 번의 작업으로 모든 작업을 수행하고 수정 된 벡터를 한 번만 참조하므로 더 좋습니다.
Olexa

1
@Olexa : 집합 차이는 벡터에서 주어진 숫자 집합의 모든 발생을 제거하는 것과 항상 동일 a하지는 않습니다 remove. 이것이 문제가되지 않으면을 사용할 수도 있습니다 setdiff. setdiff, BTW, 사용 match에 대한이 %in%바로 가기입니다.
SX에 불만 cbeleites

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다른 함수의 결과 일 때 매우 유용 하므로 3 대신 임시 변수 대신 한 줄로 작업을 수행 할 수 있습니다
jf328

14
이것은 상이한 결과를 생성 할 것이다 %in%입력 벡터 (케이스가되는 중복 포함 된 경우 용액 setdiff만을 단독 반환 세트 중복없이 즉,)
탈랏

2
@docendodiscimus : fsetdiffof data.tablepackage에는 all입력 벡터에 중복을 유지할 수 있는 플래그 (기본값 F)가 있습니다.
Juergen

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
예제에서 목록이라고 부르는 것은 벡터입니다.
패트릭

예, 벡터를 의미합니다. 의견 주셔서 감사합니다.
ykpemre

여기에 필요가 없습니다 which. @cbeleites 답변과 기본적으로 동일합니다.
David Arenburg

예, 비슷하지만 몇 가지 관점에서 다릅니다. whichTRUE 값의 인덱스를 반환합니다. 따라서 빼기 부호를 사용하여 "이 색인 이외의 색인"이라고 말할 수 있습니다. 또한 which자연어에 더 가깝기 때문에 더 읽기 쉽습니다.
ykpemre

4

대신에

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

패키지를 사용 purrr하고 magrittr, 당신은 할 수 있습니다 :

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

이 가능 subset팅 한 번만 벡터 이름을 사용. 그리고 파이프에서 사용할 수 있습니다 :)


변수 이름 길이에 대한 마지막 설명을 설명해 주시겠습니까? 왜 안 좋아합니까? 왜 다른 방법보다 낫습니까? 또는 주요 문제 / 질문과 관련이 없으므로 해당 단락을 제거하십시오.
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

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

@BenBolker 아 나는 "중복 된"술어를 몰랐다 : ((지금 무엇, 내 대답을 삭제하거나 대신 당신의 것만 보여 주도록 변경해야 하는가?)
Özgür

@ BenBolker, 솔루션이 잘못되었습니다. 그냥 시도하십시오 : full_vector = c(1,1,1,2,3); searched_vector = c(1,1,3);- 1, 1, 2정답 대신 생성 됩니다 1, 2.
fnl

반복되는 값에 대해 가능한 올바른 솔루션을 추가하려면 다음을 수행하십시오. 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.