3

which() 咩?

 3 years ago
source link: https://yihui.org/cn/2017/04/which/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

which() 咩?

谢益辉 / 2017-04-19


R 里面有个 which() 函数,我感觉很多人一旦学了就忘不了,总是想用。它可以把逻辑向量转化为整数向量,这些整数表示哪些位置上的值是 TRUE,如 which(c(F, T, F)) 就会返回 2。我见过好些人在用下标索引的时候硬生生把逻辑向量用 which() 转一下,比如 x[which(y)]y 是逻辑向量),这个 which() 的调用完全没必要,因为 R 有三种索引方式:整数值、逻辑值、字符(名字)。可能一般人还是习惯整数索引吧。

作为强迫症患者,我尽量不做无谓的强迫,尽管这个有点难。比如要不要提出来 which() 是不必要的,其实不能完全根据自己的喜好来判断,而是要客观测量它究竟有多糟糕。糟不糟糕,主要准则应该是速度,比如用了 which() 会导致代码显著变慢吗?理论上多调用一个函数肯定会更慢,但我用三秒钟的时间想了一下,万一 which() 慢,但整数索引比逻辑索引更快,那时间有没有可能追回来?

空谈误国,放码过来。前方测速区:

n = 100000
x = runif(n)
i = logical(n)
i[sample(n, n/4)] = TRUE

microbenchmark::microbenchmark(x[i], x[which(i)], times = 1000)

跑了一下,貌似没那么糟糕。

Unit: microseconds
        expr   min    lq  mean median    uq   max neval
        x[i] 362.4 488.6 719.6  577.2 669.7  6723  1000
 x[which(i)] 438.4 581.3 900.7  670.2 795.8 82968  1000

我还有个类似的洁癖,就是不愿意看到 if (x == TRUE) 这种写法,if (x) 就足够。去年在芝加哥参加 JSM 的时候我已经吐槽过一次。不过呢,把 TRUE 写出来倒也不是完全没有好处:它的潜在好处是快速扫描代码的时候很容易知道这里有个逻辑值,因为这四个大写字母比较耀眼。

平底锅版的煎饼果子 思源宋体

Disqus Utterances Preferences

© Yihui Xie 2005 - 2020

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK