如何从向量中删除多个值?

问题描述 投票:105回答:8

我有一个像:a = c(1:10)这样的矢量,我需要删除多个值,例如:2, 3, 5

如何在向量中删除这些数字(它们不是向量中的位置)?

此刻我循环向量并执行以下操作:

a[!a=NUMBER_TO_REMOVE]

但我认为有一个功能可以自动完成。

r
8个回答
172
投票

%in%运算符会告诉您要删除的数字中的哪些元素:

> 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

请注意,这将默默地删除不兼容的东西(像NAInf)这样的东西(虽然它会在a中保留重复值,只要它们没有在remove中列出)。

  • 如果a可以包含不兼容,但remove不会,我们可以使用match,告诉它返回0的非匹配和不可比(%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)] (这不区分NANaN,但R手册反正警告说不应该依赖它们之间的区别) 对于Inf / -Inf,你必须检查signis.finite

85
投票

你可以使用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

6
投票

你可以这样做:

> 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)]

3
投票

代替

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

使用包purrrmargrittr,你可以这样做:

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

这允许仅使用向量名称进行一次子集化。你可以在管道中使用它:)


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)]

1
投票

更新:

所有上述答案都不适用于重复值,@ BenBolker使用duplicated()谓词的答案解决了这个问题:

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
投票
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),它显示错误删除(q [c(11,12,13)])如果您尝试此操作,您将看到删除功能对向量编号不起作用。你删除整个矢量但可能不是一个单一的元素。


0
投票

还有subset有时可能有用:

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

> subset(a, !(a %in% bad))
[1]  9  7 10  6  8  1  4
© www.soinside.com 2019 - 2024. All rights reserved.