gpt4 book ai didi

r - 负索引子集 : best practices?

转载 作者:行者123 更新时间:2023-12-01 12:25:45 25 4
gpt4 key购买 nike

假设我有一个子集函数(这只是一个最小的例子):

f <- function(x, ind = seq(length(x))) {
x[ind]
}

(注意:可以只使用seq(x)而不是seq(length(x)),但我觉得不是很清楚。)

所以,如果

x <- 1:5
ind <- c(2, 4)
ind2 <- which(x > 5) # integer(0)

我有以下结果:

f(x) 
[1] 1 2 3 4 5
f(x, ind)
[1] 2 4
f(x, -ind)
[1] 1 3 5
f(x, ind2)
integer(0)
f(x, -ind2)
integer(0)

对于最后的结果,我们希望得到所有的 x,但这是一个常见的错误原因(如 Advanced R 一书中所述)。

所以,如果我想创建一个删除索引的函数,我会使用:

f2 <- function(x, ind.rm) {
f(x, ind = `if`(length(ind.rm) > 0, -ind.rm, seq(length(x))))
}

然后我得到了我想要的:

f2(x, ind)
[1] 1 3 5
f2(x, ind2)
[1] 1 2 3 4 5

我的问题是:我可以做一些更干净的事情吗?不需要在 f2 中显式传递 seq(length(x)) 而是直接使用 f 的默认值> 的参数 indind.rminteger(0) 时?

最佳答案

如果您预计会有很多“空”负索引,那么如果您可以避免 x[seq(x)] 使用的索引而不是仅仅使用索引,则可以提高这些情况的性能x。换句话说,如果您能够将 ff2 组合成如下内容:

new_f <- function(x, ind.rm){
if(length(ind.rm)) x[-ind.rm] else x
}

在空负索引的情况下会有巨大的加速。

n <- 1000000L
x <- 1:n
ind <- seq(0L,n,2L)
ind2 <- which(x>n+1) # integer(0)

library(microbenchmark)
microbenchmark(
f2(x, ind),
new_f(x, ind),
f2(x, ind2),
new_f(x, ind2)
)
all.equal(f2(x, ind), new_f(x, ind)) # TRUE - same result at about same speed
all.equal(f2(x, ind2), new_f(x, ind2)) # TRUE - same result at much faster speed

Unit: nanoseconds
expr min lq mean median uq max neval
f2(x, ind) 6223596 7377396.5 11039152.47 9317005 10271521 50434514 100
new_f(x, ind) 6190239 7398993.0 11129271.17 9239386 10202882 59717093 100
f2(x, ind2) 6823589 7992571.5 11267034.52 9217149 10568524 63417978 100
new_f(x, ind2) 428 1283.5 5414.74 6843 7271 14969 100

关于r - 负索引子集 : best practices?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40026975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com