当子集长度为零时如何简洁地处理子集? [英] How to concisely deal with subsets when their lengths become zero?

查看:26
本文介绍了当子集长度为零时如何简洁地处理子集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从向量中排除元素 x,

x <- c(1, 4, 3, 2)

我们可以减去一个位置向量:

we can subtract a vector of positions:

excl <- c(2, 3)
x[-excl]
# [1] 1 2

这也是动态的,

(excl <- which(x[-which.max(x)] > quantile(x, .25)))
# [1] 2 3
x[-excl]
# [1] 1 2

直到 excl 的长度为零:

excl.nolength <- which(x[-which.max(x)] > quantile(x, .95))
length(excl.nolength)
# [1] 0
x[-excl.nolength]
# integer(0)

我可以重新表述一下,但是我有许多应用了 excl 的对象,例如:

I could kind of reformulate that, but I have many objects to which excl is applied, say:

letters[1:4][-excl.nolength]
# character(0)

我知道我可以使用 setdiff,但它很长且难以阅读:

I know I could use setdiff, but that's rather long and hard to read:

x[setdiff(seq(x), excl.nolength)]
# [1] 1 4 3 2

letters[1:4][setdiff(seq(letters[1:4]), excl.nolength)]
# [1] "a" "b" "c" "d"

现在,我可以利用以下事实:如果元素数量大于元素数量,则不会排除任何内容:

Now, I could exploit the fact that nothing is excluded if the element number is greater than the number of elements:

length(x)
# [1] 4
x[-5]
# [1] 1 4 3 2

概括地说,我可能应该使用 .Machine$integer.max:

To generalize that I should probably use .Machine$integer.max:

tmp <- which(x[-which.max(x)] > quantile(x, .95))
excl <- if (!length(tmp) == 0) tmp else .Machine$integer.max
x[-excl]
# [1] 1 4 3 2

封装成一个函数,

e <- function(x) if (!length(x) == 0) x else .Machine$integer.max

这非常方便和清晰:

x[-e(excl)]
# [1] 1 2

x[-e(excl.nolength)]
# [1] 1 4 3 2

letters[1:4][-e(excl.nolength)]
# [1] "a" "b" "c" "d"

但对我来说似乎有点可疑...

But it seems a little fishy to me...

是否有更好的同样简洁的方法来处理基数 R 中长度为零的子集?

Is there a better equally concise way to deal with a subset of length zero in base R?

excl 之前作为函数的动态结果出现(如上面的 which 所示)并且长度可能为零或不为零.如果 length(excl) == 0 什么都不应该被排除.以下代码行,例如x[-excl] 最好不要改动,也尽可能少改动.

excl comes out as dynamic result of a function before (as shown with which above) and might be of length zero or not. If length(excl) == 0 nothing should be excluded. Following lines of code, e.g. x[-excl] should not have to be changed at best or as little as possible.

推荐答案

你可以用你自己的函数覆盖[.

You can overwrite [ with your own function.

"["  <- function(x,y) {if(length(y)==0) x else .Primitive("[")(x,y)}

x <- c(1, 4, 3, 2)
excl <- c(2, 3)
x[-excl]
#[1] 1 2
excl <- integer()
x[-excl]
#[1] 1 4 3 2

rm("[") #Go back to normal mode

这篇关于当子集长度为零时如何简洁地处理子集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆