%in% 的对面:排除具有向量中指定值的行
Posted
技术标签:
【中文标题】%in% 的对面:排除具有向量中指定值的行【英文标题】:Opposite of %in%: exclude rows with values specified in a vector 【发布时间】:2011-08-15 11:09:17 【问题描述】:数据框 D1 中的分类变量 V1 可以具有由从 A 到 Z 的字母表示的值。我想创建一个子集 D2,它不包括某些值,例如 B、N 和 T。基本上,我想要一个与%in%
相反的命令
D2 = subset(D1, V1 %in% c("B", "N", "T"))
【问题讨论】:
不是 %in%? (!(x %in% y)
)。生活有时很容易......
How I can select rows from a dataframe that do not match? 的可能重复项
【参考方案1】:
怎么样:
`%ni%` <- Negate(`%in%`)
c(1,3,11) %ni% 1:10
# [1] FALSE FALSE TRUE
【讨论】:
这个实际上不起作用,因为它抛出了一个关于SPECIAL
%ni
的错误
仍然可以正常工作。 R 版本 4.0.3 (2020-10-10) 平台:x86_64-apple-darwin17.0 (64-bit) 运行于:macOS Big Sur 10.16
因为'
不是`
,你应该使用`
已进行更改。谢谢。【参考方案2】:
在 Frank Harrell 的 R 实用函数包中,他有一个 %nin% (不在),它完全符合原始问题的要求。无需再造***。
【讨论】:
【参考方案3】:包折叠已内置:%!in%
。
【讨论】:
【参考方案4】:这对我来说很好用:
`%nin%` <- Negate(`%in%`)
【讨论】:
【参考方案5】:library(roperators)
1 %ni% 2:10
如果您经常需要使用自定义中缀运算符,将它们放在一个包中比在每个脚本或项目中一遍又一遍地声明相同的确切函数更容易。
【讨论】:
虽然这可能是一个正确的答案,但如果对它的 为什么 起作用,它会更有用。如果您觉得它比近十年前发布的公认答案更好,请考虑对其进行编辑以包含更多详细信息。【参考方案6】:require(TSDT)
c(1,3,11) %nin% 1:10
# [1] FALSE FALSE TRUE
更多信息可以参考:https://cran.r-project.org/web/packages/TSDT/TSDT.pdf
【讨论】:
【参考方案7】:Hmisc 有%nin%
功能,应该这样做。
https://www.rdocumentation.org/packages/Hmisc/versions/4.4-0/topics/%25nin%25
【讨论】:
【参考方案8】:%in% 的帮助,help("%in%")
,在示例部分包含了 not in 的定义,
"%w/o%" <- function(x, y) x[!x %in% y] #-- x without y
让我们试试吧:
c(2,3,4) %w/o% c(2,8,9)
[1] 3 4
或者
"%w/o%" <- function(x, y) !x %in% y #-- x without y
c(2,3,4) %w/o% c(2,8,9)
# [1] FALSE TRUE TRUE
【讨论】:
【参考方案9】:您可以使用!
运算符基本上使任何 TRUE FALSE 和每个 FALSE TRUE。所以:
D2 = subset(D1, !(V1 %in% c('B','N','T')))
编辑: 您也可以自己制作运算符:
'%!in%' <- function(x,y)!('%in%'(x,y))
c(1,3,11)%!in%1:10
[1] FALSE FALSE TRUE
【讨论】:
帮助(匹配)页面中说明了第二个选项的使用(如果您输入?"%in%"
,您将进入该页面),其中新运算符称为 %w/o%
。
另见?Negate
例如"%ni%" <- Negate("%in%")
Negate 在定义新运算符后使用时为我工作,如 baptiste 所建议的那样,例如subset(df, variable %ni% c("A", "B"))
,但不能直接使用,例如subset(df, variable Negate("%in%") c("A", "B"))
@PatrickT 那是因为只有运算符可以用作运算符。和运算符要么是内置的,要么以%
开头和结尾。要创建运算符,您需要将具有两个操作数的函数分配给以%
开头和结尾的名称。
我们也可以使用filter(!(V1%in% c('B','N','T')))
。【参考方案10】:
这是在dplyr
中使用filter
的版本,它通过用! 否定逻辑来应用与接受的答案相同的技术:
D2 <- D1 %>% dplyr::filter(!V1 %in% c('B','N','T'))
【讨论】:
【参考方案11】:使用来自purrr
的negate
也可以快速而巧妙地完成任务:
`%not_in%` <- purrr::negate(`%in%`)
然后用法是,例如,
c("cat", "dog") %not_in% c("dog", "mouse")
【讨论】:
还有一个内置的Negate
可以做同样的事情。唯一的区别是,purrr 在你传递的东西上调用as_mapper
,而Negate
调用match.fun
。 rdocumentation.org/packages/purrr/versions/0.2.5/topics/…stat.ethz.ch/R-manual/R-devel/library/base/html/match.fun.html【参考方案12】:
purrr::compose()
是另一种快速定义它以供以后使用的方法,如下所示:
`%!in%` <- compose(`!`, `%in%`)
【讨论】:
【参考方案13】:另一种解决方案可能是使用setdiff
D1 = c("A",..., "Z") ; D0 = c("B","N","T")
D2 = setdiff(D1, D0)
D2
是您想要的子集。
【讨论】:
有时它可能很有用,但如果重复,它不会产生相同的结果。【参考方案14】:如果你看%in%
的代码
function (x, table) match(x, table, nomatch = 0L) > 0L
那么您应该能够编写相反的版本。我用
`%not in%` <- function (x, table) is.na(match(x, table, nomatch=NA_integer_))
另一种方式是:
function (x, table) match(x, table, nomatch = 0L) == 0L
【讨论】:
以上是关于%in% 的对面:排除具有向量中指定值的行的主要内容,如果未能解决你的问题,请参考以下文章
T-SQL - 有没有一种方法可以根据表中指定值的行数动态输出列?